From dmlb@ragnet.demon.co.uk  Sun Nov 22 10:31:02 1998
Received: from post.mail.demon.net (post-11.mail.demon.net [194.217.242.40])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA29402
          for <FreeBSD-gnats-submit@freebsd.org>; Sun, 22 Nov 1998 10:31:00 -0800 (PST)
          (envelope-from dmlb@ragnet.demon.co.uk)
Received: from [158.152.46.40] (helo=ragnet.demon.co.uk)
	by post.mail.demon.net with smtp (Exim 2.053 #1)
	id 0zheHA-0003YA-00
	for FreeBSD-gnats-submit@freebsd.org; Sun, 22 Nov 1998 18:30:25 +0000
Received: from dmlb by ragnet.demon.co.uk with local (Exim 1.82 #1)
	id 0zhc3E-0004BV-00; Sun, 22 Nov 1998 16:07:52 +0000
Message-Id: <E0zhc3E-0004BV-00@ragnet.demon.co.uk>
Date: Sun, 22 Nov 1998 16:07:52 +0000
From: dmlb@ragnet.demon.co.uk
Reply-To: dmlb@ragnet.demon.co.uk
To: FreeBSD-gnats-submit@freebsd.org
Cc: dmlb@ragnet.demon.co.uk
Subject: MFC, bug fix and addition to mount_portal
X-Send-Pr-Version: 3.2

>Number:         8793
>Category:       kern
>Synopsis:       mount_portal update/bug fix/addition
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Nov 22 10:40:00 PST 1998
>Closed-Date:    Tue Dec 15 11:06:09 PST 1998
>Last-Modified:  Tue Dec 15 11:06:34 PST 1998
>Originator:     Duncan Barclay
>Release:        FreeBSD 2.2.6-RELEASE i386
>Organization:
>Environment:

	Stable 

>Description:

	mount_portal is broken, when run and an attempt is made to
	open a socket with
	$ cat /p/tcp/localhost/daytime
	an error will occur. This is due to bugs in the call to sendmsg
	in send_reply(), activate.c.

	I will be doing the same for -current in the next day or so.

	There is also a security issue in pt_tcp.c and opening
	privilaged ports. I think the whole code is bogus but will
	submit another pr dealing with it.

	I am finishing off code to implement the tcplisten namespace.
	This will be done today/tomorrow. A usr/share/examples directory
	is also in prepartion. The manual page bogusly suggests I've
	finsished it!

>How-To-Repeat:

	$ mount_portal /etc/portal.conf /p
	$ cat /p/tcp/localhost/daytime
	Nov 22 11:07:54 computer portald[4459]: send: Invalid argument

>Fix:
	
	Patches included below, diff'd against stable CVSup'd 06:30 22/11/98.

Index: Makefile
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/Makefile,v
retrieving revision 1.4
diff -u -r1.4 Makefile
--- Makefile	1995/02/21 04:05:17	1.4
+++ Makefile	1998/11/22 14:42:03
@@ -3,7 +3,7 @@
 
 PROG=	mount_portal
 SRCS=	mount_portal.c activate.c conf.c getmntopts.c pt_conf.c \
-	pt_exec.c pt_file.c pt_tcp.c
+	pt_exec.c pt_file.c pt_tcp.c
 MAN8=	mount_portal.8
 
 MOUNT=	${.CURDIR}/../mount
Index: activate.c
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/activate.c,v
retrieving revision 1.1.1.1.8.1
diff -u -r1.1.1.1.8.1 activate.c
--- activate.c	1998/07/17 20:13:32	1.1.1.1.8.1
+++ activate.c	1998/11/22 14:53:10
@@ -112,7 +112,7 @@
 int error;
 {
 	int n;
-	struct iovec iov;
+	struct iovec iov[1];
 	struct msghdr msg;
 	struct {
 		struct cmsghdr cmsg;
@@ -123,15 +123,17 @@
 	 * Line up error code.  Don't worry about byte ordering
 	 * because we must be sending to the local machine.
 	 */
-	iov.iov_base = (caddr_t) &error;
-	iov.iov_len = sizeof(error);
+	iov[0].iov_base = (caddr_t) &error;
+	iov[0].iov_len = sizeof(error);
 
 	/*
 	 * Build a msghdr
 	 */
 	memset(&msg, 0, sizeof(msg));
-	msg.msg_iov = &iov;
+	msg.msg_iov = iov;
 	msg.msg_iovlen = 1;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
 
 	/*
 	 * If there is a file descriptor to send then
@@ -149,7 +151,7 @@
 	/*
 	 * Send to kernel...
 	 */
-	if ((n = sendmsg(so, &msg, MSG_EOR)) < 0)
+	if ((n = sendmsg(so, &msg, 0)) < 0)
 		syslog(LOG_ERR, "send: %s", strerror(errno));
 #ifdef DEBUG
 	fprintf(stderr, "sent %d bytes\n", n);
@@ -207,6 +209,10 @@
 		error = ENOENT;
 	}
 
+#ifdef DEBUG
+	fprintf(stderr, "returning fd = %d\n", fd);
+	fprintf(stderr, "       error = %d [%s]\n", error, strerror(error));
+#endif DEBUG
 	if (error >= 0)
 		send_reply(so, fd, error);
 
Index: conf.c
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/conf.c,v
retrieving revision 1.3
diff -u -r1.3 conf.c
--- conf.c	1995/05/30 06:09:25	1.3
+++ conf.c	1998/11/22 14:21:28
@@ -203,7 +203,7 @@
 		if (val) {
 			char errbuf[_POSIX2_LINE_MAX];
 			regerror(val, &p->p_rx, errbuf, sizeof errbuf);
-			syslog(LOG_ERR, "%s:%s: regcomp %s: %s",
+			syslog(LOG_ERR, "%s:%d: regcomp %s: %s",
 			       conf_file, curp->p_lno, curp->p_key, errbuf);
 			regfree(&p->p_rx);
 			p->p_rxvalid = 0;
Index: mount_portal.8
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/mount_portal.8,v
retrieving revision 1.2.2.1
diff -u -r1.2.2.1 mount_portal.8
--- mount_portal.8	1998/07/17 20:13:33	1.2.2.1
+++ mount_portal.8	1998/11/22 15:32:22
@@ -89,11 +89,22 @@
 By convention, the portal daemon divides the namespace into sub-namespaces,
 each of which handles objects of a particular type.
 .Pp
-Currently, two sub-namespaces are implemented:
+Currently, three sub-namespaces are implemented:
+.Pa tcplisten ,
 .Pa tcp
 and
 .Pa fs .
 The
+.Pa tcplisten
+namespace takes a slash separated hostname and port and creates a TCP/IP
+socket bound to the given hostname-port pair. The hostname may be
+specified as "ANY" to allow any other host to connect to the socket. A
+port number of 0 will dynamically allocate a port, this can be
+discovered by calling
+.Xr getsockname 8
+with the returned file descriptor. Privilaged ports can only be bound to
+by the super-user.
+The
 .Pa tcp
 namespace takes a hostname and a port (slash separated) and
 creates an open TCP/IP connection.
@@ -116,6 +127,7 @@
 Subsequent fields are passed to the creation function.
 .Bd -literal
 # @(#)portal.conf	5.1 (Berkeley) 7/13/92
+tcplisten/	tcplisten tcplisten/
 tcp/		tcp tcp/
 fs/		file fs/
 .Ed
Index: mount_portal.c
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/mount_portal.c,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 mount_portal.c
--- mount_portal.c	1997/12/04 07:36:13	1.7.2.2
+++ mount_portal.c	1998/11/22 14:50:27
@@ -93,7 +93,7 @@
 		;
 	/* wrtp - waitpid _doesn't_ return 0 when no children! */
 #ifdef notdef
-	if (pid < 0)
+	if (pid < 0 && errno != ECHILD)
 		syslog(LOG_WARNING, "waitpid: %s", strerror(errno));
 #endif
 }
@@ -122,7 +122,7 @@
 	 */
 	int ch;
 
-	while ((ch = getopt(argc, argv, "o:")) !=  -1) {
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
 		switch (ch) {
 		case 'o':
 			getmntopts(optarg, mopts, &mntflags, 0);
@@ -178,7 +178,7 @@
 	if(!vfc && vfsisloadable("portal")) {
 		if(vfsload("portal"))
 			err(EX_OSERR, "vfsload(portal)");
-		endvfsent();	/* flush cache */
+		endvfsent();
 		vfc = getvfsbyname("portal");
 	}
 	if (!vfc)
@@ -188,10 +188,10 @@
 	if (rc < 0)
 		err(1, NULL);
 
-#ifdef notdef
 	/*
 	 * Everything is ready to go - now is a good time to fork
 	 */
+#ifndef DEBUG
 	daemon(0, 0);
 #endif
 
@@ -275,7 +275,7 @@
 		case 0:
 			(void) close(so);
 			activate(&q, so2);
-			exit(0);		/* stupid errors.... tidied up... wrtp*/
+			exit(0);
 		default:
 			(void) close(so2);
 			break;
Index: portald.h
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/portald.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 portald.h
--- portald.h	1994/05/26 06:34:33	1.1.1.1
+++ portald.h	1998/11/22 14:40:08
@@ -73,6 +73,8 @@
 				char *key, char **v, int so, int *fdp));
 extern int portal_tcp __P((struct portal_cred *,
 				char *key, char **v, int so, int *fdp));
 
 /*
  * Global functions
Index: pt_conf.c
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/pt_conf.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pt_conf.c
--- pt_conf.c	1994/05/26 06:34:33	1.1.1.1
+++ pt_conf.c	1998/11/22 14:39:36
@@ -47,5 +47,6 @@
 	{ "exec",	portal_exec },
 	{ "file",	portal_file },
 	{ "tcp",	portal_tcp },
 	{ 0, 0 }
 };
Index: pt_tcp.c
===================================================================
RCS file: /ide0.e/ncvs/src/sbin/mount_portal/pt_tcp.c,v
retrieving revision 1.2.6.1
diff -u -r1.2.6.1 pt_tcp.c
--- pt_tcp.c	1998/08/12 06:27:34	1.2.6.1
+++ pt_tcp.c	1998/11/22 15:20:52
@@ -62,11 +62,11 @@
  * An unrecognized suffix is an error.
  */
 int portal_tcp(pcr, key, v, kso, fdp)
-struct portal_cred *pcr;
-char *key;
-char **v;
-int kso;
-int *fdp;
+	struct portal_cred *pcr;
+	char *key;
+	char **v;
+	int kso;
+	int *fdp;
 {
 	char host[MAXHOSTNAMELEN];
 	char port[MAXHOSTNAMELEN];
@@ -122,18 +122,19 @@
 #endif
 
 	sp = getservbyname(port, "tcp");
-	if (sp != NULL)
+	if (sp != NULL) {
 		s_port = (u_short)sp->s_port;
-	else {
-		s_port = htons ((u_short)strtol (port, (char**)NULL, 10));
-		if (s_port == 0)
+	} else {
+		s_port = strtoul(port, &p, 0);
+		if (s_port == 0 || *p != '\0')
 			return (EINVAL);
+		s_port = htons(s_port);
 	}
 #ifdef DEBUG
-	printf ("port number for %s is %d\n", port, s_port);
+	printf ("port number for %s is %d\n", port, ntohs(s_port));
 #endif
 
-	bzero(&sain, sizeof(sain));
+	memset(&sain, 0, sizeof(sain));
 	sain.sin_len = sizeof(sain);
 	sain.sin_family = AF_INET;
 	sain.sin_port = s_port;
>Release-Note:
>Audit-Trail:

From: Duncan Barclay <dmlb@ragnet.demon.co.uk>
To: freebsd-gnats-submit@freebsd.org
Cc:  Subject: Re: kern/8793: mount_portal update/bug fix/additioN
Date: Sun, 22 Nov 1998 23:05:20 -0000 (GMT)

 This PR should be read in conjunction with
 o [1998/11/22] kern/8793  mount_portal update/bug fix/addition
 o [1998/11/22] misc/8796: Addition to /usr/share/examples
 o [1998/11/22] kern/8797  addition of tcplisten namespace to portal FS
 o [1998/11/22] kern/8798  Bug to to portal code.
 
 This fixes
 o [1998/09/25] kern/8050  Portal Filesystem (mount_portal) does not operate
                           correctly.
 s [1998/05/25] kern/6758  mount_portal fails because kernal refuses to accept
                           MSG_EOR flag in sendmsg
 
 And doesn't do anything with
 o [1997/09/13] kern/4528  processes hang if the mount_portal process dies.
 
 Duncan
 
 ---
 ________________________________________________________________________
 Duncan Barclay          | God smiles upon the little children,
 dmlb@ragnet.demon.co.uk | the alcoholics, and the permanently stoned.
 ________________________________________________________________________
State-Changed-From-To: open->closed 
State-Changed-By: dillon 
State-Changed-When: Tue Dec 15 11:06:09 PST 1998 
State-Changed-Why:  
Committed adjustments to freebsd-current 
>Unformatted:
