diff options
author | jilles <jilles@FreeBSD.org> | 2012-09-29 11:54:34 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2012-09-29 11:54:34 +0000 |
commit | fba61ef227067b4f30ac71dee816dd39abee1c8e (patch) | |
tree | 89610d7c33533a1abd5218d8db331931ee9e6327 /lib/libc | |
parent | 576f4f1ec84faf13f14984bdf7f8f07357e3ab02 (diff) | |
download | FreeBSD-src-fba61ef227067b4f30ac71dee816dd39abee1c8e.zip FreeBSD-src-fba61ef227067b4f30ac71dee816dd39abee1c8e.tar.gz |
libc: Use O_CLOEXEC for various internal file descriptors.
This fixes a race condition where another thread may fork() before CLOEXEC
is set, unintentionally passing the descriptor to the child process.
This commit only adds O_CLOEXEC flags to open() or openat() calls where no
fcntl(fd, F_SETFD, FD_CLOEXEC) follows. The separate fcntl() call still
leaves a race window so it should be fixed later.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/arc4random.c | 2 | ||||
-rw-r--r-- | lib/libc/gen/getcap.c | 2 | ||||
-rw-r--r-- | lib/libc/gen/getcwd.c | 2 | ||||
-rw-r--r-- | lib/libc/gen/nlist.c | 2 | ||||
-rw-r--r-- | lib/libc/gen/opendir.c | 3 | ||||
-rw-r--r-- | lib/libc/gen/pututxline.c | 6 | ||||
-rw-r--r-- | lib/libc/gen/readpassphrase.c | 2 | ||||
-rw-r--r-- | lib/libc/gen/sem_new.c | 2 | ||||
-rw-r--r-- | lib/libc/gen/syslog.c | 3 | ||||
-rw-r--r-- | lib/libc/locale/ldpart.c | 2 | ||||
-rw-r--r-- | lib/libc/nls/msgcat.c | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/rand.c | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/random.c | 2 | ||||
-rw-r--r-- | lib/libc/yp/yplib.c | 2 |
14 files changed, 18 insertions, 16 deletions
diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c index 46059ab..59e410b 100644 --- a/lib/libc/gen/arc4random.c +++ b/lib/libc/gen/arc4random.c @@ -153,7 +153,7 @@ arc4_stir(void) if (arc4_sysctl((u_char *)&rdat, KEYSIZE) == KEYSIZE) done = 1; if (!done) { - fd = _open(RANDOMDEV, O_RDONLY, 0); + fd = _open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) done = 1; diff --git a/lib/libc/gen/getcap.c b/lib/libc/gen/getcap.c index 2700d3d..c321d12 100644 --- a/lib/libc/gen/getcap.c +++ b/lib/libc/gen/getcap.c @@ -264,7 +264,7 @@ getent(char **cap, u_int *len, char **db_array, int fd, const char *name, *cap = cbuf; return (retval); } else { - fd = _open(*db_p, O_RDONLY, 0); + fd = _open(*db_p, O_RDONLY | O_CLOEXEC, 0); if (fd < 0) continue; myfd = 1; diff --git a/lib/libc/gen/getcwd.c b/lib/libc/gen/getcwd.c index 40feedf..da76d56 100644 --- a/lib/libc/gen/getcwd.c +++ b/lib/libc/gen/getcwd.c @@ -142,7 +142,7 @@ getcwd(pt, size) /* Open and stat parent directory. */ fd = _openat(dir != NULL ? _dirfd(dir) : AT_FDCWD, - "..", O_RDONLY); + "..", O_RDONLY | O_CLOEXEC); if (fd == -1) goto err; if (dir) diff --git a/lib/libc/gen/nlist.c b/lib/libc/gen/nlist.c index 1361af3..159731c 100644 --- a/lib/libc/gen/nlist.c +++ b/lib/libc/gen/nlist.c @@ -66,7 +66,7 @@ nlist(name, list) { int fd, n; - fd = _open(name, O_RDONLY, 0); + fd = _open(name, O_RDONLY | O_CLOEXEC, 0); if (fd < 0) return (-1); n = __fdnlist(fd, list); diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c index 4366399..2d505fc 100644 --- a/lib/libc/gen/opendir.c +++ b/lib/libc/gen/opendir.c @@ -199,7 +199,8 @@ __opendir_common(int fd, const char *name, int flags) * which has also been read -- see fts.c. */ if (flags & DTF_REWIND) { - if ((fd2 = _open(name, O_RDONLY | O_DIRECTORY)) == -1) { + if ((fd2 = _open(name, O_RDONLY | O_DIRECTORY | + O_CLOEXEC)) == -1) { saved_errno = errno; free(buf); free(dirp); diff --git a/lib/libc/gen/pututxline.c b/lib/libc/gen/pututxline.c index 98addee..555386c 100644 --- a/lib/libc/gen/pututxline.c +++ b/lib/libc/gen/pututxline.c @@ -47,7 +47,7 @@ futx_open(const char *file) struct stat sb; int fd; - fd = _open(file, O_CREAT|O_RDWR|O_EXLOCK, 0644); + fd = _open(file, O_CREAT|O_RDWR|O_EXLOCK|O_CLOEXEC, 0644); if (fd < 0) return (NULL); @@ -235,7 +235,7 @@ utx_lastlogin_upgrade(void) struct stat sb; int fd; - fd = _open(_PATH_UTX_LASTLOGIN, O_RDWR, 0644); + fd = _open(_PATH_UTX_LASTLOGIN, O_RDWR|O_CLOEXEC, 0644); if (fd < 0) return; @@ -269,7 +269,7 @@ utx_log_add(const struct futx *fu) vec[1].iov_len = l; l = htobe16(l); - fd = _open(_PATH_UTX_LOG, O_CREAT|O_WRONLY|O_APPEND, 0644); + fd = _open(_PATH_UTX_LOG, O_CREAT|O_WRONLY|O_APPEND|O_CLOEXEC, 0644); if (fd < 0) return (-1); if (_writev(fd, vec, 2) == -1) diff --git a/lib/libc/gen/readpassphrase.c b/lib/libc/gen/readpassphrase.c index d57e703..86c7811 100644 --- a/lib/libc/gen/readpassphrase.c +++ b/lib/libc/gen/readpassphrase.c @@ -68,7 +68,7 @@ restart: * stdin and write to stderr unless a tty is required. */ if ((flags & RPP_STDIN) || - (input = output = _open(_PATH_TTY, O_RDWR)) == -1) { + (input = output = _open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) { if (flags & RPP_REQUIRE_TTY) { errno = ENOTTY; return(NULL); diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c index b748b49..b11d547 100644 --- a/lib/libc/gen/sem_new.c +++ b/lib/libc/gen/sem_new.c @@ -198,7 +198,7 @@ _sem_open(const char *name, int flags, ...) goto error; } - fd = _open(path, flags|O_RDWR, mode); + fd = _open(path, flags|O_RDWR|O_CLOEXEC, mode); if (fd == -1) goto error; if (flock(fd, LOCK_EX) == -1) diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index 99308e9..6357761 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -300,7 +300,8 @@ vsyslog(int pri, const char *fmt, va_list ap) * Make sure the error reported is the one from the syslogd failure. */ if (LogStat & LOG_CONS && - (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK, 0)) >= 0) { + (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK|O_CLOEXEC, 0)) >= + 0) { struct iovec iov[2]; struct iovec *v = iov; diff --git a/lib/libc/locale/ldpart.c b/lib/libc/locale/ldpart.c index ea7b388..ccf5e7f 100644 --- a/lib/libc/locale/ldpart.c +++ b/lib/libc/locale/ldpart.c @@ -87,7 +87,7 @@ __part_load_locale(const char *name, strcat(filename, name); strcat(filename, "/"); strcat(filename, category_filename); - if ((fd = _open(filename, O_RDONLY)) < 0) + if ((fd = _open(filename, O_RDONLY | O_CLOEXEC)) < 0) return (_LDP_ERROR); if (_fstat(fd, &st) != 0) goto bad_locale; diff --git a/lib/libc/nls/msgcat.c b/lib/libc/nls/msgcat.c index 4532e90..44b1440 100644 --- a/lib/libc/nls/msgcat.c +++ b/lib/libc/nls/msgcat.c @@ -384,7 +384,7 @@ load_msgcat(const char *path, const char *name, const char *lang) } UNLOCK; - if ((fd = _open(path, O_RDONLY)) == -1) { + if ((fd = _open(path, O_RDONLY | O_CLOEXEC)) == -1) { SAVEFAIL(name, lang, errno); NLRETERR(errno); } diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c index 077c1ba..3835976 100644 --- a/lib/libc/stdlib/rand.c +++ b/lib/libc/stdlib/rand.c @@ -121,7 +121,7 @@ sranddev() int fd, done; done = 0; - fd = _open("/dev/random", O_RDONLY, 0); + fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next)) done = 1; diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c index 6da5419..4a1af54 100644 --- a/lib/libc/stdlib/random.c +++ b/lib/libc/stdlib/random.c @@ -303,7 +303,7 @@ srandomdev(void) len = rand_deg * sizeof state[0]; done = 0; - fd = _open("/dev/random", O_RDONLY, 0); + fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (_read(fd, (void *) state, len) == (ssize_t) len) done = 1; diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c index 3dfc0aa..1778c6a 100644 --- a/lib/libc/yp/yplib.c +++ b/lib/libc/yp/yplib.c @@ -375,7 +375,7 @@ again: ysd->dom_socket = -1; } snprintf(path, sizeof(path), "%s/%s.%d", BINDINGDIR, dom, 2); - if ((fd = _open(path, O_RDONLY)) == -1) { + if ((fd = _open(path, O_RDONLY | O_CLOEXEC)) == -1) { /* no binding file, YP is dead. */ /* Try to bring it back to life. */ _close(fd); |