Loading drivers/net/tun.c +32 −14 Original line number Diff line number Diff line Loading @@ -120,8 +120,8 @@ struct tun_sock; struct tun_struct { struct tun_file *tfile; unsigned int flags; uid_t owner; gid_t group; kuid_t owner; kgid_t group; struct net_device *dev; netdev_features_t set_features; Loading Loading @@ -1031,8 +1031,8 @@ static void tun_setup(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); tun->owner = -1; tun->group = -1; tun->owner = INVALID_UID; tun->group = INVALID_GID; dev->ethtool_ops = &tun_ethtool_ops; dev->destructor = tun_free_netdev; Loading Loading @@ -1155,14 +1155,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, char *buf) { struct tun_struct *tun = netdev_priv(to_net_dev(dev)); return sprintf(buf, "%d\n", tun->owner); return uid_valid(tun->owner)? sprintf(buf, "%u\n", from_kuid_munged(current_user_ns(), tun->owner)): sprintf(buf, "-1\n"); } static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, char *buf) { struct tun_struct *tun = netdev_priv(to_net_dev(dev)); return sprintf(buf, "%d\n", tun->group); return gid_valid(tun->group) ? sprintf(buf, "%u\n", from_kgid_munged(current_user_ns(), tun->group)): sprintf(buf, "-1\n"); } static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); Loading @@ -1189,8 +1195,8 @@ 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))) && if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || (gid_valid(tun->group) && !in_egroup_p(tun->group))) && !capable(CAP_NET_ADMIN)) return -EPERM; err = security_tun_dev_attach(tun->socket.sk); Loading Loading @@ -1374,6 +1380,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, void __user* argp = (void __user*)arg; struct sock_fprog fprog; struct ifreq ifr; kuid_t owner; kgid_t group; int sndbuf; int vnet_hdr_sz; int ret; Loading Loading @@ -1447,16 +1455,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, case TUNSETOWNER: /* Set owner of the device */ tun->owner = (uid_t) arg; tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); owner = make_kuid(current_user_ns(), arg); if (!uid_valid(owner)) { ret = -EINVAL; break; } tun->owner = owner; tun_debug(KERN_INFO, tun, "owner set to %d\n", from_kuid(&init_user_ns, tun->owner)); break; case TUNSETGROUP: /* Set group of the device */ tun->group= (gid_t) arg; tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); group = make_kgid(current_user_ns(), arg); if (!gid_valid(group)) { ret = -EINVAL; break; } tun->group = group; tun_debug(KERN_INFO, tun, "group set to %d\n", from_kgid(&init_user_ns, tun->group)); break; case TUNSETLINK: Loading drivers/net/wireless/airo.c +28 −20 Original line number Diff line number Diff line Loading @@ -232,8 +232,10 @@ static int adhoc; static int probe = 1; static kuid_t proc_kuid; static int proc_uid /* = 0 */; static kgid_t proc_kgid; static int proc_gid /* = 0 */; static int airo_perm = 0555; Loading Loading @@ -4499,78 +4501,79 @@ struct proc_data { static int setup_proc_entry( struct net_device *dev, struct airo_info *apriv ) { struct proc_dir_entry *entry; /* First setup the device directory */ strcpy(apriv->proc_name,dev->name); apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, airo_entry); if (!apriv->proc_entry) goto fail; apriv->proc_entry->uid = proc_uid; apriv->proc_entry->gid = proc_gid; apriv->proc_entry->uid = proc_kuid; apriv->proc_entry->gid = proc_kgid; /* Setup the StatsDelta */ entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, apriv->proc_entry, &proc_statsdelta_ops, dev); if (!entry) goto fail_stats_delta; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the Stats */ entry = proc_create_data("Stats", S_IRUGO & proc_perm, apriv->proc_entry, &proc_stats_ops, dev); if (!entry) goto fail_stats; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the Status */ entry = proc_create_data("Status", S_IRUGO & proc_perm, apriv->proc_entry, &proc_status_ops, dev); if (!entry) goto fail_status; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the Config */ entry = proc_create_data("Config", proc_perm, apriv->proc_entry, &proc_config_ops, dev); if (!entry) goto fail_config; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the SSID */ entry = proc_create_data("SSID", proc_perm, apriv->proc_entry, &proc_SSID_ops, dev); if (!entry) goto fail_ssid; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the APList */ entry = proc_create_data("APList", proc_perm, apriv->proc_entry, &proc_APList_ops, dev); if (!entry) goto fail_aplist; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the BSSList */ entry = proc_create_data("BSSList", proc_perm, apriv->proc_entry, &proc_BSSList_ops, dev); if (!entry) goto fail_bsslist; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the WepKey */ entry = proc_create_data("WepKey", proc_perm, apriv->proc_entry, &proc_wepkey_ops, dev); if (!entry) goto fail_wepkey; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; return 0; Loading Loading @@ -5697,11 +5700,16 @@ static int __init airo_init_module( void ) { int i; proc_kuid = make_kuid(&init_user_ns, proc_uid); proc_kgid = make_kgid(&init_user_ns, proc_gid); if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid)) return -EINVAL; airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); if (airo_entry) { airo_entry->uid = proc_uid; airo_entry->gid = proc_gid; airo_entry->uid = proc_kuid; airo_entry->gid = proc_kgid; } for (i = 0; i < 4 && io[i] && irq[i]; i++) { Loading fs/namei.c +3 −3 Original line number Diff line number Diff line Loading @@ -678,7 +678,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) /* Allowed if owner and follower match. */ inode = link->dentry->d_inode; if (current_cred()->fsuid == inode->i_uid) if (uid_eq(current_cred()->fsuid, inode->i_uid)) return 0; /* Allowed if parent directory not sticky and world-writable. */ Loading @@ -687,7 +687,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) return 0; /* Allowed if parent directory and link owner match. */ if (parent->i_uid == inode->i_uid) if (uid_eq(parent->i_uid, inode->i_uid)) return 0; path_put_conditional(link, nd); Loading Loading @@ -757,7 +757,7 @@ static int may_linkat(struct path *link) /* Source inode owner (or CAP_FOWNER) can hardlink all they like, * otherwise, it must be a safe source. */ if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) || if (uid_eq(cred->fsuid, inode->i_uid) || safe_hardlink_source(inode) || capable(CAP_FOWNER)) return 0; Loading fs/seq_file.c +4 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/export.h> #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/cred.h> #include <asm/uaccess.h> #include <asm/page.h> Loading Loading @@ -56,6 +57,9 @@ int seq_open(struct file *file, const struct seq_operations *op) memset(p, 0, sizeof(*p)); mutex_init(&p->lock); p->op = op; #ifdef CONFIG_USER_NS p->user_ns = file->f_cred->user_ns; #endif /* * Wrappers around seq_open(e.g. swaps_open) need to be Loading include/linux/inet_diag.h +1 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,7 @@ struct inet_diag_handler { struct inet_connection_sock; int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, struct sk_buff *skb, struct inet_diag_req_v2 *req, struct user_namespace *user_ns, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh); void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, Loading Loading
drivers/net/tun.c +32 −14 Original line number Diff line number Diff line Loading @@ -120,8 +120,8 @@ struct tun_sock; struct tun_struct { struct tun_file *tfile; unsigned int flags; uid_t owner; gid_t group; kuid_t owner; kgid_t group; struct net_device *dev; netdev_features_t set_features; Loading Loading @@ -1031,8 +1031,8 @@ static void tun_setup(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); tun->owner = -1; tun->group = -1; tun->owner = INVALID_UID; tun->group = INVALID_GID; dev->ethtool_ops = &tun_ethtool_ops; dev->destructor = tun_free_netdev; Loading Loading @@ -1155,14 +1155,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, char *buf) { struct tun_struct *tun = netdev_priv(to_net_dev(dev)); return sprintf(buf, "%d\n", tun->owner); return uid_valid(tun->owner)? sprintf(buf, "%u\n", from_kuid_munged(current_user_ns(), tun->owner)): sprintf(buf, "-1\n"); } static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, char *buf) { struct tun_struct *tun = netdev_priv(to_net_dev(dev)); return sprintf(buf, "%d\n", tun->group); return gid_valid(tun->group) ? sprintf(buf, "%u\n", from_kgid_munged(current_user_ns(), tun->group)): sprintf(buf, "-1\n"); } static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); Loading @@ -1189,8 +1195,8 @@ 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))) && if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || (gid_valid(tun->group) && !in_egroup_p(tun->group))) && !capable(CAP_NET_ADMIN)) return -EPERM; err = security_tun_dev_attach(tun->socket.sk); Loading Loading @@ -1374,6 +1380,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, void __user* argp = (void __user*)arg; struct sock_fprog fprog; struct ifreq ifr; kuid_t owner; kgid_t group; int sndbuf; int vnet_hdr_sz; int ret; Loading Loading @@ -1447,16 +1455,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, case TUNSETOWNER: /* Set owner of the device */ tun->owner = (uid_t) arg; tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); owner = make_kuid(current_user_ns(), arg); if (!uid_valid(owner)) { ret = -EINVAL; break; } tun->owner = owner; tun_debug(KERN_INFO, tun, "owner set to %d\n", from_kuid(&init_user_ns, tun->owner)); break; case TUNSETGROUP: /* Set group of the device */ tun->group= (gid_t) arg; tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); group = make_kgid(current_user_ns(), arg); if (!gid_valid(group)) { ret = -EINVAL; break; } tun->group = group; tun_debug(KERN_INFO, tun, "group set to %d\n", from_kgid(&init_user_ns, tun->group)); break; case TUNSETLINK: Loading
drivers/net/wireless/airo.c +28 −20 Original line number Diff line number Diff line Loading @@ -232,8 +232,10 @@ static int adhoc; static int probe = 1; static kuid_t proc_kuid; static int proc_uid /* = 0 */; static kgid_t proc_kgid; static int proc_gid /* = 0 */; static int airo_perm = 0555; Loading Loading @@ -4499,78 +4501,79 @@ struct proc_data { static int setup_proc_entry( struct net_device *dev, struct airo_info *apriv ) { struct proc_dir_entry *entry; /* First setup the device directory */ strcpy(apriv->proc_name,dev->name); apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, airo_entry); if (!apriv->proc_entry) goto fail; apriv->proc_entry->uid = proc_uid; apriv->proc_entry->gid = proc_gid; apriv->proc_entry->uid = proc_kuid; apriv->proc_entry->gid = proc_kgid; /* Setup the StatsDelta */ entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, apriv->proc_entry, &proc_statsdelta_ops, dev); if (!entry) goto fail_stats_delta; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the Stats */ entry = proc_create_data("Stats", S_IRUGO & proc_perm, apriv->proc_entry, &proc_stats_ops, dev); if (!entry) goto fail_stats; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the Status */ entry = proc_create_data("Status", S_IRUGO & proc_perm, apriv->proc_entry, &proc_status_ops, dev); if (!entry) goto fail_status; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the Config */ entry = proc_create_data("Config", proc_perm, apriv->proc_entry, &proc_config_ops, dev); if (!entry) goto fail_config; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the SSID */ entry = proc_create_data("SSID", proc_perm, apriv->proc_entry, &proc_SSID_ops, dev); if (!entry) goto fail_ssid; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the APList */ entry = proc_create_data("APList", proc_perm, apriv->proc_entry, &proc_APList_ops, dev); if (!entry) goto fail_aplist; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the BSSList */ entry = proc_create_data("BSSList", proc_perm, apriv->proc_entry, &proc_BSSList_ops, dev); if (!entry) goto fail_bsslist; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; /* Setup the WepKey */ entry = proc_create_data("WepKey", proc_perm, apriv->proc_entry, &proc_wepkey_ops, dev); if (!entry) goto fail_wepkey; entry->uid = proc_uid; entry->gid = proc_gid; entry->uid = proc_kuid; entry->gid = proc_kgid; return 0; Loading Loading @@ -5697,11 +5700,16 @@ static int __init airo_init_module( void ) { int i; proc_kuid = make_kuid(&init_user_ns, proc_uid); proc_kgid = make_kgid(&init_user_ns, proc_gid); if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid)) return -EINVAL; airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); if (airo_entry) { airo_entry->uid = proc_uid; airo_entry->gid = proc_gid; airo_entry->uid = proc_kuid; airo_entry->gid = proc_kgid; } for (i = 0; i < 4 && io[i] && irq[i]; i++) { Loading
fs/namei.c +3 −3 Original line number Diff line number Diff line Loading @@ -678,7 +678,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) /* Allowed if owner and follower match. */ inode = link->dentry->d_inode; if (current_cred()->fsuid == inode->i_uid) if (uid_eq(current_cred()->fsuid, inode->i_uid)) return 0; /* Allowed if parent directory not sticky and world-writable. */ Loading @@ -687,7 +687,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) return 0; /* Allowed if parent directory and link owner match. */ if (parent->i_uid == inode->i_uid) if (uid_eq(parent->i_uid, inode->i_uid)) return 0; path_put_conditional(link, nd); Loading Loading @@ -757,7 +757,7 @@ static int may_linkat(struct path *link) /* Source inode owner (or CAP_FOWNER) can hardlink all they like, * otherwise, it must be a safe source. */ if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) || if (uid_eq(cred->fsuid, inode->i_uid) || safe_hardlink_source(inode) || capable(CAP_FOWNER)) return 0; Loading
fs/seq_file.c +4 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/export.h> #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/cred.h> #include <asm/uaccess.h> #include <asm/page.h> Loading Loading @@ -56,6 +57,9 @@ int seq_open(struct file *file, const struct seq_operations *op) memset(p, 0, sizeof(*p)); mutex_init(&p->lock); p->op = op; #ifdef CONFIG_USER_NS p->user_ns = file->f_cred->user_ns; #endif /* * Wrappers around seq_open(e.g. swaps_open) need to be Loading
include/linux/inet_diag.h +1 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,7 @@ struct inet_diag_handler { struct inet_connection_sock; int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, struct sk_buff *skb, struct inet_diag_req_v2 *req, struct user_namespace *user_ns, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh); void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, Loading