summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2012-11-04 21:42:24 +0000
committerjilles <jilles@FreeBSD.org>2012-11-04 21:42:24 +0000
commitd793145a726ef848e5e79be78b79e4e0f54cd2cf (patch)
tree969ce31ca989f0ab57d7d234f716e31b0d9b96db /libexec/rtld-elf/rtld.c
parent01c2c225d270083238186edecb2d6f9202461c0e (diff)
downloadFreeBSD-src-d793145a726ef848e5e79be78b79e4e0f54cd2cf.zip
FreeBSD-src-d793145a726ef848e5e79be78b79e4e0f54cd2cf.tar.gz
rtld: Fix fd leak with parallel dlopen and fork/exec.
Rtld did not set FD_CLOEXEC on its internal file descriptors; therefore, such a file descriptor may be passed to a process created by another thread running in parallel to dlopen() or fdlopen(). No other threads are expected to be running during parsing of the hints and libmap files but the file descriptors need not be passed to child processes so add O_CLOEXEC there as well. This change will break fdlopen() (as used by OpenPAM) on kernels without F_DUPFD_CLOEXEC (added in July). Note that running new userland on old kernels is not supported. Reviewed by: kib
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 1a7010e..bb790dd 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -1598,7 +1598,7 @@ gethints(bool nostdlib)
/* Keep from trying again in case the hints file is bad. */
hints = "";
- if ((fd = open(ld_elf_hints_path, O_RDONLY)) == -1)
+ if ((fd = open(ld_elf_hints_path, O_RDONLY | O_CLOEXEC)) == -1)
return (NULL);
if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
hdr.magic != ELFHINTS_MAGIC ||
@@ -2046,13 +2046,13 @@ load_object(const char *name, int fd_u, const Obj_Entry *refobj, int flags)
*/
fd = -1;
if (fd_u == -1) {
- if ((fd = open(path, O_RDONLY)) == -1) {
+ if ((fd = open(path, O_RDONLY | O_CLOEXEC)) == -1) {
_rtld_error("Cannot open \"%s\"", path);
free(path);
return (NULL);
}
} else {
- fd = dup(fd_u);
+ fd = fcntl(fd_u, F_DUPFD_CLOEXEC, 0);
if (fd == -1) {
_rtld_error("Cannot dup fd");
free(path);
OpenPOWER on IntegriCloud