summaryrefslogtreecommitdiffstats
path: root/usr.sbin/inetd
diff options
context:
space:
mode:
authordwmalone <dwmalone@FreeBSD.org>2003-02-23 16:54:19 +0000
committerdwmalone <dwmalone@FreeBSD.org>2003-02-23 16:54:19 +0000
commitdff9ad9d4466cd10a9d3eb787a6638565fd087c0 (patch)
tree15d6317cfceb92f4e45245d34817c0eb3807530f /usr.sbin/inetd
parent1825d6d17dc5133b018a2bacfbf1949153cc05be (diff)
downloadFreeBSD-src-dff9ad9d4466cd10a9d3eb787a6638565fd087c0.zip
FreeBSD-src-dff9ad9d4466cd10a9d3eb787a6638565fd087c0.tar.gz
Under some unusual conditions, inetd can leak a open file discriptor
into a child process. Rather than closing the discriptors manually, mark all discriptors as close-on-exec. PR: 47694 Submitted by: Max Okumoto <okumoto@ucsd.edu> Obtained from: NetBSD MFC after: 2 weeks
Diffstat (limited to 'usr.sbin/inetd')
-rw-r--r--usr.sbin/inetd/inetd.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c
index 238e727..213683c 100644
--- a/usr.sbin/inetd/inetd.c
+++ b/usr.sbin/inetd/inetd.c
@@ -544,6 +544,11 @@ main(int argc, char **argv)
syslog(LOG_ERR, "pipe: %m");
exit(EX_OSERR);
}
+ if (fcntl(signalpipe[0], F_SETFD, FD_CLOEXEC) < 0 ||
+ fcntl(signalpipe[1], F_SETFD, FD_CLOEXEC) < 0) {
+ syslog(LOG_ERR, "signalpipe: fcntl (F_SETFD, FD_CLOEXEC): %m");
+ exit(EX_OSERR);
+ }
FD_SET(signalpipe[0], &allsock);
#ifdef SANITY_CHECK
nsock++;
@@ -724,11 +729,6 @@ main(int argc, char **argv)
sigsetmask(0L);
if (pid == 0) {
if (dofork) {
- if (debug)
- warnx("+ closing from %d", maxsock);
- for (tmpint = maxsock; tmpint > 2; tmpint--)
- if (tmpint != ctrl)
- (void) close(tmpint);
sigaction(SIGALRM, &saalrm, (struct sigaction *)0);
sigaction(SIGCHLD, &sachld, (struct sigaction *)0);
sigaction(SIGHUP, &sahup, (struct sigaction *)0);
@@ -779,8 +779,17 @@ main(int argc, char **argv)
if (debug)
warnx("%d execl %s",
getpid(), sep->se_server);
- dup2(ctrl, 0);
- close(ctrl);
+ /* Clear close-on-exec. */
+ if (fcntl(ctrl, F_SETFD, 0) < 0) {
+ syslog(LOG_ERR,
+ "%s/%s: fcntl (F_SETFD, 0): %m",
+ sep->se_service, sep->se_proto);
+ _exit(EX_OSERR);
+ }
+ if (ctrl != 0) {
+ dup2(ctrl, 0);
+ close(ctrl);
+ }
dup2(0, 1);
dup2(0, 2);
if ((pwd = getpwnam(sep->se_user)) == NULL) {
@@ -1259,6 +1268,13 @@ setup(struct servtab *sep)
sep->se_service, sep->se_proto);
return;
}
+ /* Set all listening sockets to close-on-exec. */
+ if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ syslog(LOG_ERR, "%s/%s: fcntl (F_SETFD, FD_CLOEXEC): %m",
+ sep->se_service, sep->se_proto);
+ close(sep->se_fd);
+ return;
+ }
#define turnon(fd, opt) \
setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
OpenPOWER on IntegriCloud