Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Sep 2001 05:46:00 -0400 (EDT)
From:      "Andrew R. Reiter" <arr@watson.org>
To:        freebsd-audit@freebsd.org
Subject:   inetd fd_set patch
Message-ID:  <Pine.NEB.3.96L.1010913054252.93735A-200000@fledge.watson.org>

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

[-- Attachment #1 --]
Hi,

Attached is a patch that moves to dynamically allocated fd_set bit arrays.
It can also be found at:
	http://www.watson.org/~arr/fbsd-audit/usr.sbin/inetd/inetd.c.diff

Hope it helps,
Andrew


*-------------.................................................
| Andrew R. Reiter 
| arr@fledge.watson.org
| "It requires a very unusual mind
|   to undertake the analysis of the obvious" -- A.N. Whitehead

[-- Attachment #2 --]
--- inetd.c.orig	Thu Sep 13 01:46:11 2001
+++ inetd.c	Thu Sep 13 03:38:09 2001
@@ -204,6 +204,8 @@
 
 #define	SIGBLOCK	(sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
 
+#define	fd_howmany(x, y)	(((x) + ((y) - 1)) / (y))
+
 void		close_sep __P((struct servtab *));
 void		flag_signal __P((int));
 void		flag_config __P((int));
@@ -236,7 +238,8 @@
 int	debug = 0;
 int	log = 0;
 int	maxsock;			/* highest-numbered descriptor */
-fd_set	allsock;
+fd_set	*allsock;
+int	allsock_len;
 int	options;
 int	timingout;
 int	toomany = TOOMANY;
@@ -317,6 +320,9 @@
 	const char *servname;
 	int error;
 
+	maxsock = allsock_len = 0;
+	allsock = NULL;
+
 	openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
 
 	while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:")) != -1)
@@ -466,7 +472,6 @@
 	sigaction(SIGCHLD, &sa, &sachld);
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, &sapipe);
-
 	{
 		/* space for daemons to overwrite environment for ps */
 #define	DUMMYSIZE	100
@@ -479,29 +484,39 @@
 
 	if (pipe(signalpipe) != 0) {
 		syslog(LOG_ERR, "pipe: %m");
+		if (allsock)
+		    free(allsock);
 		exit(EX_OSERR);
 	}
-	FD_SET(signalpipe[0], &allsock);
 #ifdef SANITY_CHECK
 	nsock++;
 #endif
-	if (signalpipe[0] > maxsock)
+	if (signalpipe[0] > maxsock) 
 	    maxsock = signalpipe[0];
 	if (signalpipe[1] > maxsock)
 	    maxsock = signalpipe[1];
+	if (maxsock >= allsock_len) {
+	    allsock_len = maxsock + 1;
+	    if (reallocf(allsock, allsock_len * sizeof(fd_mask)) == NULL)
+		errx(1, "reallocf");
+	} 
+	
+	FD_SET(signalpipe[0], allsock);
 
 	for (;;) {
 	    int n, ctrl;
-	    fd_set readable;
+	    fd_set *readable;
 
 #ifdef SANITY_CHECK
 	    if (nsock == 0) {
 		syslog(LOG_ERR, "%s: nsock=0", __FUNCTION__);
+		if (allsock)
+			free(allsock);
 		exit(EX_SOFTWARE);
 	    }
 #endif
 	    readable = allsock;
-	    if ((n = select(maxsock + 1, &readable, (fd_set *)0,
+	    if ((n = select(maxsock + 1, readable, (fd_set *)0,
 		(fd_set *)0, (struct timeval *)0)) <= 0) {
 		    if (n < 0 && errno != EINTR) {
 			syslog(LOG_WARNING, "select: %m");
@@ -510,15 +525,19 @@
 		    continue;
 	    }
 	    /* handle any queued signal flags */
-	    if (FD_ISSET(signalpipe[0], &readable)) {
+	    if (FD_ISSET(signalpipe[0], readable)) {
 		int nsig;
 		if (ioctl(signalpipe[0], FIONREAD, &nsig) != 0) {
+		    if (allsock)
+		        free(allsock);
 		    syslog(LOG_ERR, "ioctl: %m");
 		    exit(EX_OSERR);
 		}
 		while (--nsig >= 0) {
 		    char c;
 		    if (read(signalpipe[0], &c, 1) != 1) {
+		        if (allsock)
+			    free(allsock);
 			syslog(LOG_ERR, "read: %m");
 			exit(EX_OSERR);
 		    }
@@ -538,7 +557,7 @@
 		}
 	    }
 	    for (sep = servtab; n && sep; sep = sep->se_next)
-	        if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
+	        if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, readable)) {
 		    n--;
 		    if (debug)
 			    warnx("someone wants %s", sep->se_service);
@@ -667,6 +686,8 @@
 				sep->se_bi->bi_fn == (bi_fn_t *) tcpmux) {
 				    sep = tcpmux(ctrl);
 				    if (sep == NULL) {
+					    if (allsock)
+					        free(allsock);
 					    close(ctrl);
 					    _exit(0);
 				    }
@@ -687,6 +708,8 @@
 				    if (sep->se_socktype != SOCK_STREAM)
 					recv(ctrl, buf, sizeof (buf), 0);
 				    if (dofork) {
+					if (allsock)
+				            free(allsock);
 					sleep(1);
 					_exit(0);
 				    }
@@ -714,6 +737,8 @@
 						sep->se_user);
 					if (sep->se_socktype != SOCK_STREAM)
 						recv(0, buf, sizeof (buf), 0);
+					if (allsock)
+						free(allsock);
 					_exit(EX_NOUSER);
 				}
 				grp = NULL;
@@ -726,6 +751,8 @@
 						sep->se_group);
 					if (sep->se_socktype != SOCK_STREAM)
 						recv(0, buf, sizeof (buf), 0);
+					if (allsock)
+					    free(allsock);
 					_exit(EX_NOUSER);
 				}
 				if (grp != NULL)
@@ -739,6 +766,8 @@
 						sep->se_class);
 					if (sep->se_socktype != SOCK_STREAM)
 						recv(0, buf, sizeof (buf), 0);
+					if (allsock)
+					    free(allsock);
 					_exit(EX_NOUSER);
 				}
 #endif
@@ -754,6 +783,8 @@
 					syslog(LOG_ERR,
 					 "%s: can't setusercontext(..%s..): %m",
 					 sep->se_service, sep->se_user);
+					if (allsock)
+					    free(allsock);
 					_exit(EX_OSERR);
 				}
 #else
@@ -768,6 +799,8 @@
 						syslog(LOG_ERR,
 						  "%s: can't set gid %d: %m",
 						  sep->se_service, pwd->pw_gid);
+						if (allsock)
+						    free(allsock);
 						_exit(EX_OSERR);
 					}
 					(void) initgroups(pwd->pw_name,
@@ -776,6 +809,8 @@
 						syslog(LOG_ERR,
 						  "%s: can't set uid %d: %m",
 						  sep->se_service, pwd->pw_uid);
+						if (allsock)
+						    free(allsock);
 						_exit(EX_OSERR);
 					}
 				}
@@ -788,13 +823,18 @@
 				if (sep->se_socktype != SOCK_STREAM)
 					recv(0, buf, sizeof (buf), 0);
 			    }
-			    if (dofork)
+			    if (dofork) {
+				if (allsock)
+				    free(allsock);
 				_exit(0);
+			    }			    
 		    }
 		    if (sep->se_accept && sep->se_socktype == SOCK_STREAM)
 			    close(ctrl);
 		}
 	}
+	if (allsock)
+	    free(allsock);
 }
 
 /*
@@ -950,10 +990,10 @@
 			if (sep->se_fd >= 0) {
 			      if (sep->se_maxchild > 0
 				  && sep->se_numchild == sep->se_maxchild) {
-				      if (FD_ISSET(sep->se_fd, &allsock))
+				      if (FD_ISSET(sep->se_fd, allsock))
 					  disable(sep);
 			      } else {
-				      if (!FD_ISSET(sep->se_fd, &allsock))
+				      if (!FD_ISSET(sep->se_fd, allsock))
 					  enable(sep);
 			      }
 			}
@@ -1329,7 +1369,7 @@
 	struct servtab *sep;
 {
 	if (sep->se_fd >= 0) {
-		if (FD_ISSET(sep->se_fd, &allsock))
+		if (FD_ISSET(sep->se_fd, allsock))
 			disable(sep);
 		(void) close(sep->se_fd);
 		sep->se_fd = -1;
@@ -1402,16 +1442,20 @@
 		    "%s: %s: is mux", __FUNCTION__, sep->se_service);
 		exit(EX_SOFTWARE);
 	}
-	if (FD_ISSET(sep->se_fd, &allsock)) {
+	if (FD_ISSET(sep->se_fd, allsock)) {
 		syslog(LOG_ERR,
 		    "%s: %s: not off", __FUNCTION__, sep->se_service);
 		exit(EX_SOFTWARE);
 	}
 	nsock++;
 #endif
-	FD_SET(sep->se_fd, &allsock);
 	if (sep->se_fd > maxsock)
 		maxsock = sep->se_fd;
+	allsock_len = maxsock + 1;
+	allsock = calloc(fd_howmany(allsock_len, NFDBITS), sizeof(fd_mask));
+	if (allsock == NULL)
+		errx(1, "calloc");
+	FD_SET(sep->se_fd, allsock);
 }
 
 void
@@ -1432,7 +1476,7 @@
 		    "%s: %s: is mux", __FUNCTION__, sep->se_service);
 		exit(EX_SOFTWARE);
 	}
-	if (!FD_ISSET(sep->se_fd, &allsock)) {
+	if (!FD_ISSET(sep->se_fd, allsock)) {
 		syslog(LOG_ERR,
 		    "%s: %s: not on", __FUNCTION__, sep->se_service);
 		exit(EX_SOFTWARE);
@@ -1443,7 +1487,7 @@
 	}
 	nsock--;
 #endif
-	FD_CLR(sep->se_fd, &allsock);
+	FD_CLR(sep->se_fd, allsock);
 	if (sep->se_fd == maxsock)
 		maxsock--;
 }

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1010913054252.93735A-200000>