diff options
author | 2013-02-06 09:51:40 +0000 | |
---|---|---|
committer | 2013-02-06 16:30:47 +0100 | |
commit | fd7f25b62734ecdb63ed59001ef69a1a34edc4b4 (patch) | |
tree | 9a09af6e706b04932c805f090e406059ae516587 /lib | |
parent | eca08beaf5a7b4121da27c2a927a6ecbb08a74bf (diff) |
libfuse: set close-on-exec flag on pipe file descriptors
The FUSE library may be used from any number of programs which
may also fork() + execve(), so set the close-on-exec flag to
avoid inadvertant leakage of pipe file descriptors.
While we're at it, attempt to use pipe2() since this is within a
(currently) Linux-only code path and pipe2() offers thread-safety.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse_lowlevel.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index b4ea0e3..e28cce3 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -483,6 +483,31 @@ static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp) } #ifdef HAVE_SPLICE +#if !defined(HAVE_PIPE2) || !defined(O_CLOEXEC) +static int fuse_pipe(int fds[2]) +{ + int rv = pipe(fds); + + if (rv == -1) + return rv; + + if (fcntl(fds[0], F_SETFL, O_NONBLOCK) == -1 || + fcntl(fds[1], F_SETFL, O_NONBLOCK) == -1 || + fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 || + fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) { + close(fds[0]); + close(fds[1]); + rv = -1; + } + return rv; +} +#else +static int fuse_pipe(int fds[2]) +{ + return pipe2(fds, O_CLOEXEC | O_NONBLOCK); +} +#endif + static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f) { struct fuse_ll_pipe *llp = pthread_getspecific(f->pipe_key); @@ -493,20 +518,12 @@ static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f) if (llp == NULL) return NULL; - res = pipe(llp->pipe); + res = fuse_pipe(llp->pipe); if (res == -1) { free(llp); return NULL; } - if (fcntl(llp->pipe[0], F_SETFL, O_NONBLOCK) == -1 || - fcntl(llp->pipe[1], F_SETFL, O_NONBLOCK) == -1) { - close(llp->pipe[0]); - close(llp->pipe[1]); - free(llp); - return NULL; - } - /* *the default size is 16 pages on linux */ |