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
This commit is contained in:
parent
c40f2eef16
commit
cbdbb7252f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=111324
@ -544,6 +544,11 @@ main(int argc, char **argv)
|
|||||||
syslog(LOG_ERR, "pipe: %m");
|
syslog(LOG_ERR, "pipe: %m");
|
||||||
exit(EX_OSERR);
|
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);
|
FD_SET(signalpipe[0], &allsock);
|
||||||
#ifdef SANITY_CHECK
|
#ifdef SANITY_CHECK
|
||||||
nsock++;
|
nsock++;
|
||||||
@ -724,11 +729,6 @@ main(int argc, char **argv)
|
|||||||
sigsetmask(0L);
|
sigsetmask(0L);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
if (dofork) {
|
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(SIGALRM, &saalrm, (struct sigaction *)0);
|
||||||
sigaction(SIGCHLD, &sachld, (struct sigaction *)0);
|
sigaction(SIGCHLD, &sachld, (struct sigaction *)0);
|
||||||
sigaction(SIGHUP, &sahup, (struct sigaction *)0);
|
sigaction(SIGHUP, &sahup, (struct sigaction *)0);
|
||||||
@ -779,8 +779,17 @@ main(int argc, char **argv)
|
|||||||
if (debug)
|
if (debug)
|
||||||
warnx("%d execl %s",
|
warnx("%d execl %s",
|
||||||
getpid(), sep->se_server);
|
getpid(), sep->se_server);
|
||||||
dup2(ctrl, 0);
|
/* Clear close-on-exec. */
|
||||||
close(ctrl);
|
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, 1);
|
||||||
dup2(0, 2);
|
dup2(0, 2);
|
||||||
if ((pwd = getpwnam(sep->se_user)) == NULL) {
|
if ((pwd = getpwnam(sep->se_user)) == NULL) {
|
||||||
@ -1259,6 +1268,13 @@ setup(struct servtab *sep)
|
|||||||
sep->se_service, sep->se_proto);
|
sep->se_service, sep->se_proto);
|
||||||
return;
|
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) \
|
#define turnon(fd, opt) \
|
||||||
setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
|
setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
|
||||||
if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
|
if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
|
||||||
|
Loading…
Reference in New Issue
Block a user