X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Ftun.c;fp=drivers%2Fnet%2Ftun.c;h=3f5d28851aa20e4b175a05133faf27161f199f0c;hb=d7e9660ad9d5e0845f52848bce31bcf5cdcdea6b;hp=589a44acdc76ec7c77949beed85c713f612f6ce7;hpb=13af7a6ea502fcdd4c0e3d7de6e332b102309491;p=mv-sheeva.git diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 589a44acdc7..3f5d28851aa 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -127,17 +127,10 @@ static inline struct tun_sock *tun_sk(struct sock *sk) static int tun_attach(struct tun_struct *tun, struct file *file) { struct tun_file *tfile = file->private_data; - const struct cred *cred = current_cred(); int err; ASSERT_RTNL(); - /* Check permissions */ - if (((tun->owner != -1 && cred->euid != tun->owner) || - (tun->group != -1 && !in_egroup_p(tun->group))) && - !capable(CAP_NET_ADMIN)) - return -EPERM; - netif_tx_lock_bh(tun->dev); err = -EINVAL; @@ -926,6 +919,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { + const struct cred *cred = current_cred(); + if (ifr->ifr_flags & IFF_TUN_EXCL) return -EBUSY; if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) @@ -935,6 +930,14 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) else return -EINVAL; + if (((tun->owner != -1 && cred->euid != tun->owner) || + (tun->group != -1 && !in_egroup_p(tun->group))) && + !capable(CAP_NET_ADMIN)) + return -EPERM; + err = security_tun_dev_attach(tun->socket.sk); + if (err < 0) + return err; + err = tun_attach(tun, file); if (err < 0) return err; @@ -947,6 +950,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (!capable(CAP_NET_ADMIN)) return -EPERM; + err = security_tun_dev_create(); + if (err < 0) + return err; /* Set dev type */ if (ifr->ifr_flags & IFF_TUN) { @@ -988,6 +994,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) container_of(sk, struct tun_sock, sk)->tun = tun; + security_tun_dev_post_create(sk); + tun_net_init(dev); if (strchr(dev->name, '%')) {