diff --git a/CHANGELOG b/CHANGELOG index 8e46930..3362689 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,6 +21,7 @@ - fix potential file handle leakage in rpc_subs.c for some failure cases. - fix file handle leak in included map lookup. - fix "-fstype=nfs4" server probing. +- set close-on-exec flag on open files where possible. 1/9/2006 autofs-5.0.1 rc2 ------------------------- diff --git a/daemon/direct.c b/daemon/direct.c index 327768d..d2b75f9 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -81,7 +81,7 @@ static void key_mnt_params_init(void) static int autofs_init_direct(struct autofs_point *ap) { - int pipefd[2]; + int pipefd[2], cl_flags; if ((ap->state != ST_INIT)) { /* This can happen if an autofs process is already running*/ @@ -102,6 +102,16 @@ static int autofs_init_direct(struct aut ap->pipefd = pipefd[0]; ap->kpipefd = pipefd[1]; + if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->pipefd, F_SETFD, cl_flags); + } + + if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->kpipefd, F_SETFD, cl_flags); + } + /* Pipe state changes from signal handler to main loop */ if (pipe(ap->state_pipe) < 0) { crit(ap->logopt, "failed create state pipe for autofs path %s", @@ -110,6 +120,17 @@ static int autofs_init_direct(struct aut close(ap->kpipefd); return -1; } + + if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->state_pipe[0], F_SETFD, cl_flags); + } + + if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->state_pipe[1], F_SETFD, cl_flags); + } + return 0; } @@ -133,8 +154,18 @@ int do_umount_autofs_direct(struct autof return 1; } ioctlfd = me->ioctlfd; - } else + } else { + int cl_flags; + ioctlfd = open(me->key, O_RDONLY); + if (ioctlfd != -1) { + if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ioctlfd, F_SETFD, cl_flags); + } + } + } + if (ioctlfd >= 0) { int status = 1; @@ -305,7 +336,7 @@ int do_mount_autofs_direct(struct autofs struct mnt_params *mp; time_t timeout = ap->exp_timeout; struct stat st; - int status, ret, ioctlfd; + int status, ret, ioctlfd, cl_flags; struct list_head list; INIT_LIST_HEAD(&list); @@ -317,8 +348,16 @@ int do_mount_autofs_direct(struct autofs save_ioctlfd = ioctlfd = me->ioctlfd; - if (ioctlfd == -1) + if (ioctlfd == -1) { ioctlfd = open(me->key, O_RDONLY); + if (ioctlfd != -1) { + cl_flags = fcntl(ioctlfd, F_GETFD, 0); + if (cl_flags != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ioctlfd, F_SETFD, cl_flags); + } + } + } if (ioctlfd < 0) { error(ap->logopt, @@ -405,6 +444,11 @@ int do_mount_autofs_direct(struct autofs goto out_umount; } + if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ioctlfd, F_SETFD, cl_flags); + } + /* Only calculate this first time round */ if (ap->kver.major) goto got_version; @@ -526,7 +570,7 @@ int mount_autofs_direct(struct autofs_po int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) { char buf[MAX_ERR_BUF]; - int ioctlfd, rv = 1, retries; + int ioctlfd, cl_flags, rv = 1, retries; if (me->ioctlfd != -1) { if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) { @@ -535,8 +579,15 @@ int umount_autofs_offset(struct autofs_p return 1; } ioctlfd = me->ioctlfd; - } else + } else { ioctlfd = open(me->key, O_RDONLY); + if (ioctlfd != -1) { + if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ioctlfd, F_SETFD, cl_flags); + } + } + } if (ioctlfd >= 0) { int status = 1; @@ -622,7 +673,7 @@ int mount_autofs_offset(struct autofs_po struct mnt_params *mp; time_t timeout = ap->exp_timeout; struct stat st; - int ioctlfd, status, ret; + int ioctlfd, cl_flags, status, ret; if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { if (ap->state != ST_READMAP) @@ -719,6 +770,11 @@ int mount_autofs_offset(struct autofs_po goto out_umount; } + if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ioctlfd, F_SETFD, cl_flags); + } + ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout); ret = fstat(ioctlfd, &st); @@ -1299,7 +1355,7 @@ int handle_packet_missing_direct(struct struct pending_args *mt; char buf[MAX_ERR_BUF]; int status = 0; - int ioctlfd, state; + int ioctlfd, cl_flags, state; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); @@ -1345,6 +1401,11 @@ int handle_packet_missing_direct(struct return 1; } + if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ioctlfd, F_SETFD, cl_flags); + } + debug(ap->logopt, "token %ld, name %s, request pid %u", (unsigned long) pkt->wait_queue_token, me->key, pkt->pid); diff --git a/daemon/indirect.c b/daemon/indirect.c index 8a5fa2c..608f37b 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -45,7 +45,7 @@ static pthread_mutex_t ea_mutex = PTHREA static int autofs_init_indirect(struct autofs_point *ap) { - int pipefd[2]; + int pipefd[2], cl_flags; if ((ap->state != ST_INIT)) { /* This can happen if an autofs process is already running*/ @@ -67,6 +67,16 @@ static int autofs_init_indirect(struct a ap->pipefd = pipefd[0]; ap->kpipefd = pipefd[1]; + if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->pipefd, F_SETFD, cl_flags); + } + + if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->kpipefd, F_SETFD, cl_flags); + } + /* Pipe state changes from signal handler to main loop */ if (pipe(ap->state_pipe) < 0) { crit(ap->logopt, @@ -77,6 +87,16 @@ static int autofs_init_indirect(struct a return -1; } + if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->state_pipe[0], F_SETFD, cl_flags); + } + + if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->state_pipe[1], F_SETFD, cl_flags); + } + return 0; } @@ -129,7 +149,7 @@ static int do_mount_autofs_indirect(stru char *options = NULL; struct stat st; struct mnt_list *mnts; - int ret; + int cl_flags, ret; mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1); if (mnts) { @@ -183,6 +203,11 @@ static int do_mount_autofs_indirect(stru goto out_umount; } + if ((cl_flags = fcntl(ap->ioctlfd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(ap->ioctlfd, F_SETFD, cl_flags); + } + ap->kver.major = 0; ap->kver.minor = 0; diff --git a/lib/nss_parse.y b/lib/nss_parse.y index 76ef934..68620f1 100644 --- a/lib/nss_parse.y +++ b/lib/nss_parse.y @@ -25,6 +25,7 @@ #include #include #include #include +#include #include #include "automount.h" @@ -124,13 +125,21 @@ static int nss_error(const char *s) int nsswitch_parse(struct list_head *list) { FILE *nsswitch; - int status; + int fd, cl_flags, status; nsswitch = fopen(NSSWITCH_FILE, "r"); if (!nsswitch) { error(LOGOPT_ANY, "couldn't open %s\n", NSSWITCH_FILE); return 1; } + + fd = fileno(nsswitch); + + if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, cl_flags); + } + nss_in = nsswitch; nss_list = list; diff --git a/modules/lookup_file.c b/modules/lookup_file.c index b0d09e7..d09afac 100644 --- a/modules/lookup_file.c +++ b/modules/lookup_file.c @@ -18,6 +18,7 @@ #include #include #include #include +#include #include #include #include @@ -357,6 +358,7 @@ int lookup_read_master(struct master *ma char *ent; struct stat st; FILE *f; + int fd, cl_flags; unsigned int path_len, ent_len; int entry, cur_state; @@ -392,6 +394,13 @@ int lookup_read_master(struct master *ma return NSS_STATUS_UNAVAIL; } + fd = fileno(f); + + if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, cl_flags); + } + master_init_scan(); while(1) { entry = read_one(f, path, &path_len, ent, &ent_len); @@ -453,7 +462,7 @@ int lookup_read_master(struct master *ma break; } - if (fstat(fileno(f), &st)) { + if (fstat(fd, &st)) { crit(LOGOPT_ANY, MODPREFIX "file map %s, could not stat", ctxt->mapname); return NSS_STATUS_UNAVAIL; @@ -608,6 +617,7 @@ int lookup_read_map(struct autofs_point char *mapent; struct stat st; FILE *f; + int fd, cl_flags; unsigned int k_len, m_len; int entry; @@ -647,6 +657,13 @@ int lookup_read_map(struct autofs_point return NSS_STATUS_UNAVAIL; } + fd = fileno(f); + + if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, cl_flags); + } + while(1) { entry = read_one(f, key, &k_len, mapent, &m_len); if (!entry) { @@ -704,7 +721,7 @@ int lookup_read_map(struct autofs_point break; } - if (fstat(fileno(f), &st)) { + if (fstat(fd, &st)) { crit(ap->logopt, MODPREFIX "file map %s, could not stat", ctxt->mapname); @@ -728,6 +745,7 @@ static int lookup_one(struct autofs_poin char mapent[MAPENT_MAX_LEN + 1]; time_t age = time(NULL); FILE *f; + int fd, cl_flags; unsigned int k_len, m_len; int entry, ret; @@ -744,6 +762,13 @@ static int lookup_one(struct autofs_poin return CHE_FAIL; } + fd = fileno(f); + + if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, cl_flags); + } + while(1) { entry = read_one(f, mkey, &k_len, mapent, &m_len); if (entry) { @@ -829,6 +854,7 @@ static int lookup_wild(struct autofs_poi char mapent[MAPENT_MAX_LEN + 1]; time_t age = time(NULL); FILE *f; + int fd, cl_flags; unsigned int k_len, m_len; int entry, ret; @@ -845,6 +871,13 @@ static int lookup_wild(struct autofs_poi return CHE_FAIL; } + fd = fileno(f); + + if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, cl_flags); + } + while(1) { entry = read_one(f, mkey, &k_len, mapent, &m_len); if (entry) { diff --git a/modules/mount_changer.c b/modules/mount_changer.c index b817d36..6e04c7c 100644 --- a/modules/mount_changer.c +++ b/modules/mount_changer.c @@ -152,6 +152,7 @@ int swapCD(const char *device, const cha { int fd; /* file descriptor for CD-ROM device */ int status; /* return status for system calls */ + int cl_flags; int slot = -1; int total_slots_available; @@ -165,6 +166,11 @@ int swapCD(const char *device, const cha return 1; } + if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { + cl_flags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, cl_flags); + } + /* Check CD player status */ total_slots_available = ioctl(fd, CDROM_CHANGER_NSLOTS); if (total_slots_available <= 1) {