diff options
author | Jeff Dike <jdike@addtoit.com> | 2006-02-07 12:58:41 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-07 16:12:32 -0800 |
commit | 1d2ddcfb1935c9c0e98c4295458b01f24e3274f9 (patch) | |
tree | 94bc4ad32840430b22e22057dbf8deb70e72492a | |
parent | fbd5577901388ff9306a05eb63648c30e4722134 (diff) |
[PATCH] uml: close TUN/TAP file descriptors
When UML opens a TUN/TAP device, the file descriptor could be copied into
later, long-lived threads, holding the device open even after the interface is
taken down, preventing it from being brought up again. This patch makes these
descriptors close-on-exec so that they disappear from helper processes, and
adds CLONE_FILES to a UML helper thread so that the descriptors are closed in
the thread when they are closed elsewhere in UML.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/um/drivers/chan_user.c | 15 | ||||
-rw-r--r-- | arch/um/os-Linux/drivers/tuntap_user.c | 4 |
2 files changed, 10 insertions, 9 deletions
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 5d50d4a44ab..2f880cb167a 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -9,6 +9,7 @@ #include <termios.h> #include <string.h> #include <signal.h> +#include <sched.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/socket.h> @@ -73,7 +74,6 @@ static void winch_handler(int sig) struct winch_data { int pty_fd; int pipe_fd; - int close_me; }; static int winch_thread(void *arg) @@ -84,7 +84,6 @@ static int winch_thread(void *arg) int count, err; char c = 1; - os_close_file(data->close_me); pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; count = os_write_file(pipe_fd, &c, sizeof(c)); @@ -153,15 +152,16 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) } data = ((struct winch_data) { .pty_fd = fd, - .pipe_fd = fds[1], - .close_me = fds[0] } ); - err = run_helper_thread(winch_thread, &data, 0, &stack, 0); + .pipe_fd = fds[1] } ); + /* CLONE_FILES so this thread doesn't hold open files which are open + * now, but later closed. This is a problem with /dev/net/tun. + */ + err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ printk("fork of winch_thread failed - errno = %d\n", errno); goto out_close; } - os_close_file(fds[1]); *fd_out = fds[0]; n = os_read_file(fds[0], &c, sizeof(c)); if(n != sizeof(c)){ @@ -169,13 +169,12 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) printk("read failed, err = %d\n", -n); printk("fd %d will not support SIGWINCH\n", fd); err = -EINVAL; - goto out_close1; + goto out_close; } return err ; out_close: os_close_file(fds[1]); - out_close1: os_close_file(fds[0]); out: return err; diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 52945338b64..87c3aa0252d 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -122,6 +122,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, return(-EINVAL); } *fd_out = ((int *) CMSG_DATA(cmsg))[0]; + os_set_exec_close(*fd_out, 1); return(0); } @@ -137,7 +138,8 @@ static int tuntap_open(void *data) return(err); if(pri->fixed_config){ - pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0); + pri->fd = os_open_file("/dev/net/tun", + of_cloexec(of_rdwr(OPENFLAGS())), 0); if(pri->fd < 0){ printk("Failed to open /dev/net/tun, err = %d\n", -pri->fd); |