Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Jul 2001 01:12:13 -0700
From:      Kris Kennaway <kris@obsecurity.org>
To:        Kris Kennaway <kris@obsecurity.org>
Cc:        audit@FreeBSD.ORG
Subject:   Re: syslogd signal/string patch
Message-ID:  <20010724011213.A4758@xor.obsecurity.org>
In-Reply-To: <20010724004956.A4293@xor.obsecurity.org>; from kris@obsecurity.org on Tue, Jul 24, 2001 at 12:49:56AM -0700
References:  <20010724003529.A3687@xor.obsecurity.org> <20010724004956.A4293@xor.obsecurity.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--LQksG6bCIzRHxTLp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Jul 24, 2001 at 12:49:56AM -0700, Kris Kennaway wrote:
> On Tue, Jul 24, 2001 at 12:35:29AM -0700, Kris Kennaway wrote:
> > It seems to work :)
>=20
> No it doesn't (looks like the child process is spinning on the CPU).

Stupid off-by-one bug :)

I also changed an exit() in a signal handler introduced by FreeBSD to
_exit(), which I think is correct.  There's an errx() in there as
well; is that okay?

Kris

Index: syslogd.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mnt/ncvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.79
diff -u -r1.79 syslogd.c
--- syslogd.c	2001/07/02 15:26:47	1.79
+++ syslogd.c	2001/07/24 08:10:42
@@ -282,6 +282,9 @@
 				/* 0=3Dno, 1=3Dnumeric, 2=3Dnames */
 int	KeepKernFac =3D 0;	/* Keep remotely logged kernel facility */
=20
+sig_atomic_t MarkSet;
+sig_atomic_t WantDie;
+
 int	allowaddr __P((char *));
 void	cfline __P((char *, struct filed *, char *, char *));
 char   *cvthname __P((struct sockaddr *));
@@ -289,6 +292,7 @@
 int	deadq_remove __P((pid_t));
 int	decode __P((const char *, CODE *));
 void	die __P((int));
+void	dodie __P((int));
 void	domark __P((int));
 void	fprintlog __P((struct filed *, int, char *));
 int*	socksetup __P((int));
@@ -296,6 +300,7 @@
 void	logerror __P((const char *));
 void	logmsg __P((int, char *, char *, int));
 void	log_deadchild __P((pid_t, int, const char *));
+void	markit __P((void));
 void	printline __P((char *, char *));
 void	printsys __P((char *));
 int	p_open __P((char *, pid_t *));
@@ -314,14 +319,15 @@
 	int argc;
 	char *argv[];
 {
-	int ch, i, l;
+	int ch, i, l, fdsrmax =3D 0;
 	struct sockaddr_un sunx, fromunix;
 	struct sockaddr_storage frominet;
+	fd_set *fdsr =3D NULL;
 	FILE *fp;
 	char *p, *hname, line[MAXLINE + 1];
-	struct timeval tv, *tvp;
 	struct sigaction sact;
 	sigset_t mask;
+	struct timeval tv, *tvp;
 	pid_t ppid =3D 1;
 	socklen_t len;
=20
@@ -397,17 +403,18 @@
 		endservent();
=20
 	consfile.f_type =3D F_CONSOLE;
-	(void)strcpy(consfile.f_un.f_fname, ctty + sizeof _PATH_DEV - 1);
+	(void)strlcpy(consfile.f_un.f_fname, ctty + sizeof _PATH_DEV - 1,
+	    sizeof(consfile.f_un.f_fname));
 	(void)gethostname(LocalHostName, sizeof(LocalHostName));
 	if ((p =3D strchr(LocalHostName, '.')) !=3D NULL) {
 		*p++ =3D '\0';
 		LocalDomain =3D p;
 	} else
 		LocalDomain =3D "";
-	(void)strcpy(bootfile, getbootfile());
-	(void)signal(SIGTERM, die);
-	(void)signal(SIGINT, Debug ? die : SIG_IGN);
-	(void)signal(SIGQUIT, Debug ? die : SIG_IGN);
+	(void)strlcpy(bootfile, getbootfile(), sizeof(bootfile));
+	(void)signal(SIGTERM, dodie);
+	(void)signal(SIGINT, Debug ? dodie : SIG_IGN);
+	(void)signal(SIGQUIT, Debug ? dodie : SIG_IGN);
 	/*
 	 * We don't want the SIGCHLD and SIGHUP handlers to interfere
 	 * with each other; they are likely candidates for being called
@@ -432,7 +439,7 @@
 	for (i =3D 0; i < nfunix; i++) {
 		memset(&sunx, 0, sizeof(sunx));
 		sunx.sun_family =3D AF_UNIX;
-		(void)strncpy(sunx.sun_path, funixn[i], sizeof(sunx.sun_path));
+		(void)strlcpy(sunx.sun_path, funixn[i], sizeof(sunx.sun_path));
 		funix[i] =3D socket(AF_UNIX, SOCK_DGRAM, 0);
 		if (funix[i] < 0 ||
 		    bind(funix[i], (struct sockaddr *)&sunx,
@@ -490,53 +497,65 @@
 	tvp =3D &tv;
 	tv.tv_sec =3D tv.tv_usec =3D 0;
=20
+	if (fklog !=3D -1 && fklog > fdsrmax)
+		fdsrmax =3D fklog;
+	if (finet && !SecureMode) {
+		for (i =3D 0; i < *finet; i++) {
+		    if (finet[i+1] !=3D -1 && finet[i+1] > fdsrmax)
+			fdsrmax =3D finet[i+1];
+		}
+	}
+	for (i =3D 0; i < nfunix; i++) {
+		if (funix[i] !=3D -1 && funix[i] > fdsrmax)
+			fdsrmax =3D funix[i];
+	}
+
+	fdsr =3D (fd_set *)calloc(howmany(fdsrmax+1, NFDBITS),
+	    sizeof(fd_mask));
+	if (fdsr =3D=3D NULL)
+		errx(1, "calloc fd_set");
+
 	for (;;) {
-		fd_set readfds;
-		int nfds =3D 0;
+		if (MarkSet)
+			markit();
+		if (WantDie)
+			die(WantDie);
=20
-		FD_ZERO(&readfds);
-		if (fklog !=3D -1) {
-			FD_SET(fklog, &readfds);
-			if (fklog > nfds)
-				nfds =3D fklog;
-		}
+		bzero(fdsr, howmany(fdsrmax+1, NFDBITS) *
+		    sizeof(fd_mask));
+
+		if (fklog !=3D -1)
+			FD_SET(fklog, fdsr);
 		if (finet && !SecureMode) {
 			for (i =3D 0; i < *finet; i++) {
-				FD_SET(finet[i+1], &readfds);
-				if (finet[i+1] > nfds)
-					nfds =3D finet[i+1];
+				if (finet[i+1] !=3D -1)
+					FD_SET(finet[i+1], fdsr);
 			}
 		}
 		for (i =3D 0; i < nfunix; i++) {
-			if (funix[i] !=3D -1) {
-				FD_SET(funix[i], &readfds);
-				if (funix[i] > nfds)
-					nfds =3D funix[i];
-			}
+			if (funix[i] !=3D -1)
+				FD_SET(funix[i], fdsr);
 		}
=20
-		/*dprintf("readfds =3D %#x\n", readfds);*/
-		nfds =3D select(nfds+1, &readfds, (fd_set *)NULL,
-			      (fd_set *)NULL, tvp);
-		if (nfds =3D=3D 0) {
+		i =3D select(fdsrmax+1, fdsr, NULL, NULL, tvp);
+		switch (i) {
+		case 0:
 			if (tvp) {
 				tvp =3D NULL;
 				if (ppid !=3D 1)
 					kill(ppid, SIGALRM);
 			}
 			continue;
-		}
-		if (nfds < 0) {
+		case -1:
 			if (errno !=3D EINTR)
 				logerror("select");
 			continue;
 		}
-		/*dprintf("got a message (%d, %#x)\n", nfds, readfds);*/
-		if (fklog !=3D -1 && FD_ISSET(fklog, &readfds))
+		if (fklog !=3D -1 && FD_ISSET(fklog, fdsr))
 			readklog();
 		if (finet && !SecureMode) {
 			for (i =3D 0; i < *finet; i++) {
-				if (FD_ISSET(finet[i+1], &readfds)) {
+				if (FD_ISSET(finet[i+1], fdsr)) {
 					len =3D sizeof(frominet);
 					l =3D recvfrom(finet[i+1], line, MAXLINE,
 					     0, (struct sockaddr *)&frominet,
@@ -553,7 +572,7 @@
 			}
 		}
 		for (i =3D 0; i < nfunix; i++) {
-			if (funix[i] !=3D -1 && FD_ISSET(funix[i], &readfds)) {
+			if (funix[i] !=3D -1 && FD_ISSET(funix[i], fdsr)) {
 				len =3D sizeof(fromunix);
 				l =3D recvfrom(funix[i], line, MAXLINE, 0,
 				    (struct sockaddr *)&fromunix, &len);
@@ -565,6 +584,8 @@
 			}
 		}
 	}
+	if (fdsr)
+		free(fdsr);
 }
=20
 static void
@@ -843,7 +864,7 @@
 		if ((flags & MARK) =3D=3D 0 && msglen =3D=3D f->f_prevlen &&
 		    !strcmp(msg, f->f_prevline) &&
 		    !strcasecmp(from, f->f_prevhost)) {
-			(void)strncpy(f->f_lasttime, timestamp, 15);
+			(void)strlcpy(f->f_lasttime, timestamp, 16);
 			f->f_prevcount++;
 			dprintf("msg repeated %d times, %ld sec of %d\n",
 			    f->f_prevcount, (long)(now - f->f_time),
@@ -864,13 +885,12 @@
 				fprintlog(f, 0, (char *)NULL);
 			f->f_repeatcount =3D 0;
 			f->f_prevpri =3D pri;
-			(void)strncpy(f->f_lasttime, timestamp, 15);
-			(void)strncpy(f->f_prevhost, from,
-					sizeof(f->f_prevhost)-1);
-			f->f_prevhost[sizeof(f->f_prevhost)-1] =3D '\0';
+			strlcpy(f->f_lasttime, timestamp, 16);
+			strlcpy(f->f_prevhost, from,
+			    sizeof(f->f_prevhost));
 			if (msglen < MAXSVLINE) {
 				f->f_prevlen =3D msglen;
-				(void)strcpy(f->f_prevline, msg);
+				strlcpy(f->f_prevline, msg, sizeof(f->f_prevline));
 				fprintlog(f, flags, (char *)NULL);
 			} else {
 				f->f_prevline[0] =3D 0;
@@ -968,8 +988,8 @@
 		v->iov_len =3D strlen(msg);
 	} else if (f->f_prevcount > 1) {
 		v->iov_base =3D repbuf;
-		v->iov_len =3D sprintf(repbuf, "last message repeated %d times",
-		    f->f_prevcount);
+		v->iov_len =3D snprintf(repbuf, sizeof repbuf,
+		    "last message repeated %d times", f->f_prevcount);
 	} else {
 		v->iov_base =3D f->f_prevline;
 		v->iov_len =3D f->f_prevlen;
@@ -1124,8 +1144,7 @@
 	while (fread((char *)&ut, sizeof(ut), 1, uf) =3D=3D 1) {
 		if (ut.ut_name[0] =3D=3D '\0')
 			continue;
-		strncpy(line, ut.ut_line, sizeof(ut.ut_line));
-		line[sizeof(ut.ut_line)] =3D '\0';
+		strlcpy(line, ut.ut_line, sizeof(line));
 		if (f->f_type =3D=3D F_WALL) {
 			if ((p =3D ttymsg(iov, 7, line, TTYMSGTIME)) !=3D NULL) {
 				errno =3D 0;	/* already in msg */
@@ -1227,56 +1246,17 @@
 }
=20
 void
-domark(signo)
+dodie(signo)
 	int signo;
 {
-	struct filed *f;
-	dq_t q;
-
-	now =3D time((time_t *)NULL);
-	MarkSeq +=3D TIMERINTVL;
-	if (MarkSeq >=3D MarkInterval) {
-		logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK);
-		MarkSeq =3D 0;
-	}
-
-	for (f =3D Files; f; f =3D f->f_next) {
-		if (f->f_prevcount && now >=3D REPEATTIME(f)) {
-			dprintf("flush %s: repeated %d times, %d sec.\n",
-			    TypeNames[f->f_type], f->f_prevcount,
-			    repeatinterval[f->f_repeatcount]);
-			fprintlog(f, 0, (char *)NULL);
-			BACKOFF(f);
-		}
-	}
-
-	/* Walk the dead queue, and see if we should signal somebody. */
-	for (q =3D TAILQ_FIRST(&deadq_head); q !=3D NULL; q =3D TAILQ_NEXT(q, dq_=
entries))
-		switch (q->dq_timeout) {
-		case 0:
-			/* Already signalled once, try harder now. */
-			if (kill(q->dq_pid, SIGKILL) !=3D 0)
-				(void)deadq_remove(q->dq_pid);
-			break;
-
-		case 1:
-			/*
-			 * Timed out on dead queue, send terminate
-			 * signal.  Note that we leave the removal
-			 * from the dead queue to reapchild(), which
-			 * will also log the event (unless the process
-			 * didn't even really exist, in case we simply
-			 * drop it from the dead queue).
-			 */
-			if (kill(q->dq_pid, SIGTERM) !=3D 0)
-				(void)deadq_remove(q->dq_pid);
-			/* FALLTHROUGH */
-
-		default:
-			q->dq_timeout--;
-		}
+	WantDie =3D signo;
+}
=20
-	(void)alarm(TIMERINTVL);
+void
+domark(signo)
+	int signo;
+{
+	MarkSet =3D 1;
 }
=20
 /*
@@ -1319,7 +1299,7 @@
 	Initialized =3D was_initialized;
 	if (signo) {
 		dprintf("syslogd: exiting on signal %d\n", signo);
-		(void)sprintf(buf, "exiting on signal %d", signo);
+		(void)snprintf(buf, sizeof buf, "exiting on signal %d", signo);
 		errno =3D 0;
 		logerror(buf);
 	}
@@ -1393,8 +1373,8 @@
 	 *  Foreach line in the conf table, open that file.
 	 */
 	f =3D NULL;
-	strcpy(host, "*");
-	strcpy(prog, "*");
+	strlcpy(host, "*", sizeof(host));
+	strlcpy(prog, "*", sizeof(prog));
 	while (fgets(cline, sizeof(cline), cf) !=3D NULL) {
 		/*
 		 * check for end-of-section, comments, strip off trailing
@@ -1414,7 +1394,7 @@
 			host[0] =3D *p++;
 			while (isspace(*p)) p++;
 			if ((!*p) || (*p =3D=3D '*')) {
-				strcpy(host, "*");
+				strlcpy(host, "*", sizeof(host));
 				continue;
 			}
 			if (*p =3D=3D '@')
@@ -1431,7 +1411,7 @@
 			p++;
 			while (isspace(*p)) p++;
 			if ((!*p) || (*p =3D=3D '*')) {
-				strcpy(prog, "*");
+				strlcpy(prog, "*", sizeof(prog));
 				continue;
 			}
 			for (i =3D 0; i < NAME_MAX; i++) {
@@ -1629,9 +1609,8 @@
 	switch (*p)
 	{
 	case '@':
-		(void)strncpy(f->f_un.f_forw.f_hname, ++p,
-			sizeof(f->f_un.f_forw.f_hname)-1);
-		f->f_un.f_forw.f_hname[sizeof(f->f_un.f_forw.f_hname)-1] =3D '\0';
+		(void)strlcpy(f->f_un.f_forw.f_hname, ++p,
+			sizeof(f->f_un.f_forw.f_hname));
 		memset(&hints, 0, sizeof(hints));
 		hints.ai_family =3D family;
 		hints.ai_socktype =3D SOCK_DGRAM;
@@ -1656,16 +1635,17 @@
 				f->f_type =3D F_CONSOLE;
 			else
 				f->f_type =3D F_TTY;
-			(void)strcpy(f->f_un.f_fname, p + sizeof _PATH_DEV - 1);
+			(void)strlcpy(f->f_un.f_fname, p + sizeof _PATH_DEV - 1,
+			    sizeof(f->f_un.f_fname));
 		} else {
-			(void)strcpy(f->f_un.f_fname, p);
+			(void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname));
 			f->f_type =3D F_FILE;
 		}
 		break;
=20
 	case '|':
 		f->f_un.f_pipe.f_pid =3D 0;
-		(void)strcpy(f->f_un.f_pipe.f_pname, p + 1);
+		(void)strlcpy(f->f_un.f_fname, p + 1, sizeof(f->f_un.f_fname));
 		f->f_type =3D F_PIPE;
 		break;
=20
@@ -1720,6 +1700,59 @@
 	return (-1);
 }
=20
+void
+markit(void)
+{
+	struct filed *f;
+	dq_t q;
+
+	now =3D time((time_t *)NULL);
+	MarkSeq +=3D TIMERINTVL;
+	if (MarkSeq >=3D MarkInterval) {
+		logmsg(LOG_INFO, "-- MARK --",
+		    LocalHostName, ADDDATE|MARK);
+		MarkSeq =3D 0;
+	}
+
+	for (f =3D Files; f; f =3D f->f_next) {
+		if (f->f_prevcount && now >=3D REPEATTIME(f)) {
+			dprintf("flush %s: repeated %d times, %d sec.\n",
+			    TypeNames[f->f_type], f->f_prevcount,
+			    repeatinterval[f->f_repeatcount]);
+			fprintlog(f, 0, (char *)NULL);
+			BACKOFF(f);
+		}
+	}
+
+	/* Walk the dead queue, and see if we should signal somebody. */
+	for (q =3D TAILQ_FIRST(&deadq_head); q !=3D NULL; q =3D TAILQ_NEXT(q, dq_=
entries))
+		switch (q->dq_timeout) {
+		case 0:
+			/* Already signalled once, try harder now. */
+			if (kill(q->dq_pid, SIGKILL) !=3D 0)
+				(void)deadq_remove(q->dq_pid);
+			break;
+
+		case 1:
+			/*
+			 * Timed out on dead queue, send terminate
+			 * signal.  Note that we leave the removal
+			 * from the dead queue to reapchild(), which
+			 * will also log the event (unless the process
+			 * didn't even really exist, in case we simply
+			 * drop it from the dead queue).
+			 */
+			if (kill(q->dq_pid, SIGTERM) !=3D 0)
+				(void)deadq_remove(q->dq_pid);
+			/* FALLTHROUGH */
+
+		default:
+			q->dq_timeout--;
+		}
+	MarkSet =3D 0;
+	(void)alarm(TIMERINTVL);
+}
+
 /*
  * fork off and become a daemon, but wait for the child to come online
  * before returing to the parent, or we get disk thrashing at boot etc.
@@ -1789,7 +1822,7 @@
 	if (left =3D=3D 0)
 		errx(1, "timed out waiting for child");
 	else
-		exit(0);
+		_exit(0);
 }
=20
 /*




--LQksG6bCIzRHxTLp
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE7XS3cWry0BWjoQKURAgCEAJ0Q7n6LQGJ70vAUs4Vsw6doQw99ZACfaKtT
O6Pg/euqMlhnO+Rqqr2c7d0=
=3mgD
-----END PGP SIGNATURE-----

--LQksG6bCIzRHxTLp--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010724011213.A4758>