Date: Sun, 22 Nov 1998 16:07:52 +0000 From: dmlb@ragnet.demon.co.uk To: FreeBSD-gnats-submit@FreeBSD.ORG Cc: dmlb@ragnet.demon.co.uk Subject: kern/8793: MFC, bug fix and addition to mount_portal Message-ID: <E0zhc3E-0004BV-00@ragnet.demon.co.uk>
index | next in thread | raw e-mail
>Number: 8793
>Category: kern
>Synopsis: mount_portal update/bug fix/addition
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Nov 22 10:40:00 PST 1998
>Last-Modified:
>Originator: Duncan Barclay
>Organization:
>Release: FreeBSD 2.2.6-RELEASE i386
>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;
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E0zhc3E-0004BV-00>
