Most recent kernel where this bug did not occur: 2.6.17.13 Distribution: Slackware 10.2 Problem Description: Applying TUNSETIFF ioctl needs root permissions that wasn't needed in previous versions. I was using qemu 0.8.2 (a virtual machine emulator) which uses a tap device to emulate a network between the guest and host operating system. The relevant part of the patch-2.6.18 file says: diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a1ed2d9..329d9fe 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -39,7 +39,6 @@ #define DRV_VERSION "1.6" #define DRV_DESCRIPTION "Universal TUN/TAP device driver" #define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>" -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/kernel.h> @@ -490,6 +489,9 @@ static int tun_set_iff(struct file *file err = -EINVAL; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + /* Set dev type */ if (ifr->ifr_flags & IFF_TUN) { /* TUN device */ ... I was handling security by limiting access to /dev/net/tun from a privileged unix group, but now even if I can open the /dev/net/tun device, I need CAP_NET_ADMIN to use the TUNSETIFF ioctl.
On Fri, 13 Oct 2006 14:22:48 -0700 bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=7362 > > Summary: tun/tap device needs root permission for TUNSETIFF ioctl > Kernel Version: 2.6.18 > Status: NEW > Severity: normal > Owner: jgarzik@pobox.com > Submitter: murguia@acm.org > > > Most recent kernel where this bug did not occur: 2.6.17.13 > > Distribution: Slackware 10.2 > > Problem Description: > Applying TUNSETIFF ioctl needs root permissions that wasn't needed in previous > versions. I was using qemu 0.8.2 (a virtual machine emulator) which uses a tap > device to emulate a network between the guest and host operating system. > > The relevant part of the patch-2.6.18 file says: > > diff --git a/drivers/net/tun.c b/drivers/net/tun.c > index a1ed2d9..329d9fe 100644 > --- a/drivers/net/tun.c > +++ b/drivers/net/tun.c > @@ -39,7 +39,6 @@ #define DRV_VERSION "1.6" > #define DRV_DESCRIPTION "Universal TUN/TAP device driver" > #define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>" > > -#include <linux/config.h> > #include <linux/module.h> > #include <linux/errno.h> > #include <linux/kernel.h> > @@ -490,6 +489,9 @@ static int tun_set_iff(struct file *file > > err = -EINVAL; > > + if (!capable(CAP_NET_ADMIN)) > + return -EPERM; > + > /* Set dev type */ > if (ifr->ifr_flags & IFF_TUN) { > /* TUN device */ > ... > > I was handling security by limiting access to /dev/net/tun from a privileged > unix group, but now even if I can open the /dev/net/tun device, I need > CAP_NET_ADMIN to use the TUNSETIFF ioctl. > Changelog for ca6bb5d7ab22ac79f608fe6cbc6b12de6a5a19f0 says The tuntap driver allows an admin to create persistent devices and assign ownership of them to individual users. Unfortunately, relaxing the permissions on the /dev/net/tun device node so that they can actually use those devices will _also_ allow those users to create arbitrary new devices of their own. This patch corrects that, and adjusts the recommended permissions for the device node accordingly. So I suspect you're out of luck.
Ok. It's a sound security reason. I'll try to use a workaround like creating the persistent device as root and using it as a standard user. I am closing the bug.
On Fri, 2006-10-13 at 14:43 -0700, Andrew Morton wrote: > > Problem Description: > > Applying TUNSETIFF ioctl needs root permissions that wasn't needed in previous > > versions. I was using qemu 0.8.2 (a virtual machine emulator) which uses a tap > > device to emulate a network between the guest and host operating system. > > ... > > I was handling security by limiting access to /dev/net/tun from a privileged > > unix group, but now even if I can open the /dev/net/tun device, I need > > CAP_NET_ADMIN to use the TUNSETIFF ioctl. > > > > Changelog for ca6bb5d7ab22ac79f608fe6cbc6b12de6a5a19f0 says > > The tuntap driver allows an admin to create persistent devices and > assign ownership of them to individual users. Unfortunately, relaxing > the permissions on the /dev/net/tun device node so that they can > actually use those devices will _also_ allow those users to create > arbitrary new devices of their own. This patch corrects that, and > adjusts the recommended permissions for the device node accordingly. > > So I suspect you're out of luck. You can create the device in advance, as root. Use TUNSETPERSIST and TUNSETOWNER ioctls to make it persistent and assign ownership of it to the user who runs qemu. This functionality probably ought to be in iproute2 but afaict isn't. 'ip tuntap create mode tap owner 500 persist dev tap0' would do something like this... #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/socket.h> #include <string.h> #include <linux/ioctl.h> #include <linux/if.h> #include <linux/if_tun.h> char dev[IFNAMSIZ] = "tap0"; int main(void) { struct ifreq ifr; int fd, err; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { perror("open"); return fd; } memset(&ifr, 0, sizeof(ifr)); /* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */ ifr.ifr_flags = IFF_TAP; if( *dev ) strncpy(ifr.ifr_name, dev, IFNAMSIZ); if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ close(fd); return err; } if( (err = ioctl(fd, TUNSETPERSIST, 1)) < 0 ) { perror("TUNSETPERSIST"); close(fd); return err; } if( (err = ioctl(fd, TUNSETOWNER, 500)) < 0 ){ perror("TUNSETOWNER"); close(fd); return err; } strcpy(dev, ifr.ifr_name); printf("%s\n", ifr.ifr_name); sleep(10); return fd; }