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?
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 3 Sep 2014 16:08:03 -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: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.121
diff -u -p -r1.121 syslogd.c
--- usr.sbin/syslogd/syslogd.c 31 Aug 2014 22:11:43 -0000 1.121
+++ usr.sbin/syslogd/syslogd.c 3 Sep 2014 16:40:54 -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 */
@@ -282,7 +281,7 @@ void logto_ctlconn(char *);
int
main(int argc, char *argv[])
{
- int ch, i, linesize, fd;
+ int ch, i, linesize, fd, nunix = 1;
struct sockaddr_un fromunix;
struct sockaddr_storage from;
socklen_t len;
@@ -292,6 +291,9 @@ main(int argc, char *argv[])
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 */
@@ -318,18 +320,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;
@@ -439,8 +441,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;
@@ -450,7 +452,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];
@@ -575,7 +577,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:
@@ -628,7 +630,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) {
ssize_t rlen;
Index: usr.sbin/syslogd/syslogd.h
===================================================================
RCS file: /data/mirror/openbsd/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 3 Sep 2014 16:08:03 -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 {