On Wed, Sep 03, 2014 at 06:46:26PM +0200, Alexander Bluhm wrote:
> On Fri, Aug 29, 2014 at 11:25:52PM +0200, Alexander Bluhm wrote:
> > So I will write more tests before committing this.
> 
> My regression tests found a bug in syslogd.  When adding the maximum
> number of paths with the -a option, the arrays for unix domain
> socket paths and the poll file descriptors overflow by one.
> 
> - increase pfd array by one
> - operate on size of arrays not length
> - null check for path not necessary when doing fd -1 check
> - rename variables consistently ...unix
> - make number of unix fds a local variable
> 
> ok?

After merging with my previous commit, here is the updated diff.

ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.43
diff -u -p -r1.43 privsep.c
--- usr.sbin/syslogd/privsep.c  25 Aug 2014 20:19:14 -0000      1.43
+++ usr.sbin/syslogd/privsep.c  4 Sep 2014 15:49:45 -0000
@@ -172,7 +172,7 @@ priv_init(char *conf, int numeric, int l
        close(socks[1]);
 
        /* Close descriptors that only the unpriv child needs */
-       for (i = 0; i < nfunix; i++)
+       for (i = 0; i < MAXUNIX + 1; i++)
                if (pfd[PFD_UNIX_0 + i].fd != -1)
                        close(pfd[PFD_UNIX_0 + i].fd);
        if (pfd[PFD_INET].fd != -1)
@@ -369,9 +369,9 @@ priv_init(char *conf, int numeric, int l
        close(socks[0]);
 
        /* Unlink any domain sockets that have been opened */
-       for (i = 0; i < nfunix; i++)
-               if (funixn[i] != NULL && pfd[PFD_UNIX_0 + i].fd != -1)
-                       (void)unlink(funixn[i]);
+       for (i = 0; i < MAXUNIX; i++)
+               if (pfd[PFD_UNIX_0 + i].fd != -1)
+                       (void)unlink(path_unix[i]);
        if (ctlsock_path != NULL && pfd[PFD_CTLSOCK].fd != -1)
                (void)unlink(ctlsock_path);
 
? usr.sbin/syslogd/flags
? usr.sbin/syslogd/obj
Index: usr.sbin/syslogd/privsep.c
===================================================================
RCS file: /cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.43
diff -u -p -r1.43 privsep.c
--- usr.sbin/syslogd/privsep.c  25 Aug 2014 20:19:14 -0000      1.43
+++ usr.sbin/syslogd/privsep.c  4 Sep 2014 16:00:26 -0000
@@ -172,7 +172,7 @@ priv_init(char *conf, int numeric, int l
        close(socks[1]);
 
        /* Close descriptors that only the unpriv child needs */
-       for (i = 0; i < nfunix; i++)
+       for (i = 0; i < MAXUNIX + 1; i++)
                if (pfd[PFD_UNIX_0 + i].fd != -1)
                        close(pfd[PFD_UNIX_0 + i].fd);
        if (pfd[PFD_INET].fd != -1)
@@ -369,9 +369,9 @@ priv_init(char *conf, int numeric, int l
        close(socks[0]);
 
        /* Unlink any domain sockets that have been opened */
-       for (i = 0; i < nfunix; i++)
-               if (funixn[i] != NULL && pfd[PFD_UNIX_0 + i].fd != -1)
-                       (void)unlink(funixn[i]);
+       for (i = 0; i < MAXUNIX; i++)
+               if (pfd[PFD_UNIX_0 + i].fd != -1)
+                       (void)unlink(path_unix[i]);
        if (ctlsock_path != NULL && pfd[PFD_CTLSOCK].fd != -1)
                (void)unlink(ctlsock_path);
 
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.122
diff -u -p -r1.122 syslogd.c
--- usr.sbin/syslogd/syslogd.c  4 Sep 2014 15:19:05 -0000       1.122
+++ usr.sbin/syslogd/syslogd.c  4 Sep 2014 16:00:26 -0000
@@ -183,8 +183,7 @@ char        *TypeNames[9] = {
 struct filed *Files;
 struct filed consfile;
 
-int    nfunix = 1;             /* Number of Unix domain sockets requested */
-char   *funixn[MAXFUNIX] = { _PATH_LOG }; /* Paths to Unix domain sockets */
+char   *path_unix[MAXUNIX] = { _PATH_LOG }; /* Paths to Unix domain sockets */
 int    Debug;                  /* debug flag */
 int    Startup = 1;            /* startup flag */
 char   LocalHostName[MAXHOSTNAMELEN];  /* our hostname */
@@ -289,12 +288,15 @@ void      logto_ctlconn(char *);
 int
 main(int argc, char *argv[])
 {
-       int ch, i, fd;
+       int ch, i, fd, nunix = 1;
        char *p;
        int lockpipe[2] = { -1, -1}, pair[2], nullfd;
        struct addrinfo hints, *res, *res0;
        FILE *fp;
 
+       for (i = 0; i < N_PFD; i++)
+               pfd[i].fd = -1;
+
        while ((ch = getopt(argc, argv, "46dhnuf:m:p:a:s:")) != -1)
                switch (ch) {
                case '4':               /* disable IPv6 */
@@ -321,18 +323,18 @@ main(int argc, char *argv[])
                        NoDNS = 1;
                        break;
                case 'p':               /* path */
-                       funixn[0] = optarg;
+                       path_unix[0] = optarg;
                        break;
                case 'u':               /* allow udp input port */
                        SecureMode = 0;
                        break;
                case 'a':
-                       if (nfunix >= MAXFUNIX)
+                       if (nunix >= MAXUNIX)
                                fprintf(stderr, "syslogd: "
                                    "out of descriptors, ignoring %s\n",
                                    optarg);
                        else
-                               funixn[nfunix++] = optarg;
+                               path_unix[nunix++] = optarg;
                        break;
                case 's':
                        ctlsock_path = optarg;
@@ -442,8 +444,8 @@ main(int argc, char *argv[])
 #ifndef SUN_LEN
 #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2)
 #endif
-       for (i = 0; i < nfunix; i++) {
-               if ((fd = unix_socket(funixn[i], SOCK_DGRAM, 0666)) == -1) {
+       for (i = 0; i < nunix; i++) {
+               if ((fd = unix_socket(path_unix[i], SOCK_DGRAM, 0666)) == -1) {
                        if (i == 0 && !Debug)
                                die(0);
                        continue;
@@ -453,7 +455,7 @@ main(int argc, char *argv[])
                pfd[PFD_UNIX_0 + i].events = POLLIN;
        }
 
-       nfunix++;
+       nunix++;
        if (socketpair(AF_UNIX, SOCK_DGRAM, PF_UNSPEC, pair) == -1)
                die(0);
        fd = pair[0];
@@ -578,7 +580,7 @@ main(int argc, char *argv[])
                        dprintf("syslogd: restarted\n");
                }
 
-               switch (poll(pfd, PFD_UNIX_0 + nfunix, -1)) {
+               switch (poll(pfd, PFD_UNIX_0 + nunix, -1)) {
                case 0:
                        continue;
                case -1:
@@ -603,7 +605,7 @@ main(int argc, char *argv[])
                if ((pfd[PFD_CTLCONN].revents & POLLOUT) != 0)
                        ctlconn_write_handler();
 
-               for (i = 0; i < nfunix; i++) {
+               for (i = 0; i < nunix; i++) {
                        if ((pfd[PFD_UNIX_0 + i].revents & POLLIN) != 0) {
                                unix_read_handler(pfd[PFD_UNIX_0 + i].fd);
                        }
Index: usr.sbin/syslogd/syslogd.h
===================================================================
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.h,v
retrieving revision 1.12
diff -u -p -r1.12 syslogd.h
--- usr.sbin/syslogd/syslogd.h  25 Aug 2014 18:19:18 -0000      1.12
+++ usr.sbin/syslogd/syslogd.h  4 Sep 2014 16:00:26 -0000
@@ -39,9 +39,8 @@ void send_fd(int, int);
 int  receive_fd(int);
 
 /* The list of domain sockets */
-#define MAXFUNIX       21
-extern int nfunix;
-extern char *funixn[MAXFUNIX];
+#define MAXUNIX        21
+extern char *path_unix[MAXUNIX];
 extern char *ctlsock_path;
 
 #define dprintf(_f...) do { if (Debug) printf(_f); } while (0)
@@ -55,7 +54,7 @@ extern int Startup;
 #define PFD_CTLCONN    3               /* Offset of control connection entry */
 #define PFD_INET6      4               /* Offset of inet6 socket entry */
 #define PFD_UNIX_0     5               /* Start of Unix socket entries */
-#define N_PFD          (PFD_UNIX_0 + MAXFUNIX) /* # of pollfd entries */
+#define N_PFD          (PFD_UNIX_0 + MAXUNIX + 1) /* # of pollfd entries */
 extern struct pollfd pfd[N_PFD];
 
 struct ringbuf {

Reply via email to