aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namespace.c121
-rw-r--r--fs/open.c2
-rw-r--r--fs/pnode.h5
-rw-r--r--fs/proc/root.c6
-rw-r--r--fs/sysfs/mount.c11
-rw-r--r--include/linux/capability.h1
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/kobject_ns.h2
-rw-r--r--include/linux/mount.h1
-rw-r--r--include/linux/user_namespace.h4
-rw-r--r--ipc/namespace.c2
-rw-r--r--kernel/capability.c12
-rw-r--r--kernel/fork.c5
-rw-r--r--kernel/groups.c2
-rw-r--r--kernel/nsproxy.c36
-rw-r--r--kernel/pid.c1
-rw-r--r--kernel/pid_namespace.c2
-rw-r--r--kernel/sys.c20
-rw-r--r--kernel/uid16.c2
-rw-r--r--kernel/user.c2
-rw-r--r--kernel/user_namespace.c2
-rw-r--r--kernel/utsname.c2
-rw-r--r--lib/kobject.c15
-rw-r--r--net/core/net-sysfs.c8
-rw-r--r--net/core/net_namespace.c2
-rw-r--r--net/core/scm.c4
-rw-r--r--security/commoncap.c10
27 files changed, 177 insertions, 104 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index ad8ea9bc2518..ef69fa5d2e5b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -831,6 +831,10 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
831 if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY)) 831 if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY))
832 mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; 832 mnt->mnt.mnt_flags |= MNT_LOCK_READONLY;
833 833
834 /* Don't allow unprivileged users to reveal what is under a mount */
835 if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire))
836 mnt->mnt.mnt_flags |= MNT_LOCKED;
837
834 atomic_inc(&sb->s_active); 838 atomic_inc(&sb->s_active);
835 mnt->mnt.mnt_sb = sb; 839 mnt->mnt.mnt_sb = sb;
836 mnt->mnt.mnt_root = dget(root); 840 mnt->mnt.mnt_root = dget(root);
@@ -1327,6 +1331,8 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
1327 goto dput_and_out; 1331 goto dput_and_out;
1328 if (!check_mnt(mnt)) 1332 if (!check_mnt(mnt))
1329 goto dput_and_out; 1333 goto dput_and_out;
1334 if (mnt->mnt.mnt_flags & MNT_LOCKED)
1335 goto dput_and_out;
1330 1336
1331 retval = do_umount(mnt, flags); 1337 retval = do_umount(mnt, flags);
1332dput_and_out: 1338dput_and_out:
@@ -1349,14 +1355,11 @@ SYSCALL_DEFINE1(oldumount, char __user *, name)
1349 1355
1350#endif 1356#endif
1351 1357
1352static bool mnt_ns_loop(struct path *path) 1358static bool is_mnt_ns_file(struct dentry *dentry)
1353{ 1359{
1354 /* Could bind mounting the mount namespace inode cause a 1360 /* Is this a proxy for a mount namespace? */
1355 * mount namespace loop? 1361 struct inode *inode = dentry->d_inode;
1356 */
1357 struct inode *inode = path->dentry->d_inode;
1358 struct proc_ns *ei; 1362 struct proc_ns *ei;
1359 struct mnt_namespace *mnt_ns;
1360 1363
1361 if (!proc_ns_inode(inode)) 1364 if (!proc_ns_inode(inode))
1362 return false; 1365 return false;
@@ -1365,7 +1368,19 @@ static bool mnt_ns_loop(struct path *path)
1365 if (ei->ns_ops != &mntns_operations) 1368 if (ei->ns_ops != &mntns_operations)
1366 return false; 1369 return false;
1367 1370
1368 mnt_ns = ei->ns; 1371 return true;
1372}
1373
1374static bool mnt_ns_loop(struct dentry *dentry)
1375{
1376 /* Could bind mounting the mount namespace inode cause a
1377 * mount namespace loop?
1378 */
1379 struct mnt_namespace *mnt_ns;
1380 if (!is_mnt_ns_file(dentry))
1381 return false;
1382
1383 mnt_ns = get_proc_ns(dentry->d_inode)->ns;
1369 return current->nsproxy->mnt_ns->seq >= mnt_ns->seq; 1384 return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;
1370} 1385}
1371 1386
@@ -1374,13 +1389,17 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1374{ 1389{
1375 struct mount *res, *p, *q, *r, *parent; 1390 struct mount *res, *p, *q, *r, *parent;
1376 1391
1377 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) 1392 if (!(flag & CL_COPY_UNBINDABLE) && IS_MNT_UNBINDABLE(mnt))
1393 return ERR_PTR(-EINVAL);
1394
1395 if (!(flag & CL_COPY_MNT_NS_FILE) && is_mnt_ns_file(dentry))
1378 return ERR_PTR(-EINVAL); 1396 return ERR_PTR(-EINVAL);
1379 1397
1380 res = q = clone_mnt(mnt, dentry, flag); 1398 res = q = clone_mnt(mnt, dentry, flag);
1381 if (IS_ERR(q)) 1399 if (IS_ERR(q))
1382 return q; 1400 return q;
1383 1401
1402 q->mnt.mnt_flags &= ~MNT_LOCKED;
1384 q->mnt_mountpoint = mnt->mnt_mountpoint; 1403 q->mnt_mountpoint = mnt->mnt_mountpoint;
1385 1404
1386 p = mnt; 1405 p = mnt;
@@ -1390,7 +1409,13 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1390 continue; 1409 continue;
1391 1410
1392 for (s = r; s; s = next_mnt(s, r)) { 1411 for (s = r; s; s = next_mnt(s, r)) {
1393 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(s)) { 1412 if (!(flag & CL_COPY_UNBINDABLE) &&
1413 IS_MNT_UNBINDABLE(s)) {
1414 s = skip_mnt_tree(s);
1415 continue;
1416 }
1417 if (!(flag & CL_COPY_MNT_NS_FILE) &&
1418 is_mnt_ns_file(s->mnt.mnt_root)) {
1394 s = skip_mnt_tree(s); 1419 s = skip_mnt_tree(s);
1395 continue; 1420 continue;
1396 } 1421 }
@@ -1696,6 +1721,19 @@ static int do_change_type(struct path *path, int flag)
1696 return err; 1721 return err;
1697} 1722}
1698 1723
1724static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
1725{
1726 struct mount *child;
1727 list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
1728 if (!is_subdir(child->mnt_mountpoint, dentry))
1729 continue;
1730
1731 if (child->mnt.mnt_flags & MNT_LOCKED)
1732 return true;
1733 }
1734 return false;
1735}
1736
1699/* 1737/*
1700 * do loopback mount. 1738 * do loopback mount.
1701 */ 1739 */
@@ -1713,7 +1751,7 @@ static int do_loopback(struct path *path, const char *old_name,
1713 return err; 1751 return err;
1714 1752
1715 err = -EINVAL; 1753 err = -EINVAL;
1716 if (mnt_ns_loop(&old_path)) 1754 if (mnt_ns_loop(old_path.dentry))
1717 goto out; 1755 goto out;
1718 1756
1719 mp = lock_mount(path); 1757 mp = lock_mount(path);
@@ -1731,8 +1769,11 @@ static int do_loopback(struct path *path, const char *old_name,
1731 if (!check_mnt(parent) || !check_mnt(old)) 1769 if (!check_mnt(parent) || !check_mnt(old))
1732 goto out2; 1770 goto out2;
1733 1771
1772 if (!recurse && has_locked_children(old, old_path.dentry))
1773 goto out2;
1774
1734 if (recurse) 1775 if (recurse)
1735 mnt = copy_tree(old, old_path.dentry, 0); 1776 mnt = copy_tree(old, old_path.dentry, CL_COPY_MNT_NS_FILE);
1736 else 1777 else
1737 mnt = clone_mnt(old, old_path.dentry, 0); 1778 mnt = clone_mnt(old, old_path.dentry, 0);
1738 1779
@@ -1741,6 +1782,8 @@ static int do_loopback(struct path *path, const char *old_name,
1741 goto out2; 1782 goto out2;
1742 } 1783 }
1743 1784
1785 mnt->mnt.mnt_flags &= ~MNT_LOCKED;
1786
1744 err = graft_tree(mnt, parent, mp); 1787 err = graft_tree(mnt, parent, mp);
1745 if (err) { 1788 if (err) {
1746 br_write_lock(&vfsmount_lock); 1789 br_write_lock(&vfsmount_lock);
@@ -1853,6 +1896,9 @@ static int do_move_mount(struct path *path, const char *old_name)
1853 if (!check_mnt(p) || !check_mnt(old)) 1896 if (!check_mnt(p) || !check_mnt(old))
1854 goto out1; 1897 goto out1;
1855 1898
1899 if (old->mnt.mnt_flags & MNT_LOCKED)
1900 goto out1;
1901
1856 err = -EINVAL; 1902 err = -EINVAL;
1857 if (old_path.dentry != old_path.mnt->mnt_root) 1903 if (old_path.dentry != old_path.mnt->mnt_root)
1858 goto out1; 1904 goto out1;
@@ -2389,7 +2435,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2389 2435
2390 namespace_lock(); 2436 namespace_lock();
2391 /* First pass: copy the tree topology */ 2437 /* First pass: copy the tree topology */
2392 copy_flags = CL_COPY_ALL | CL_EXPIRE; 2438 copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
2393 if (user_ns != mnt_ns->user_ns) 2439 if (user_ns != mnt_ns->user_ns)
2394 copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED; 2440 copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED;
2395 new = copy_tree(old, old->mnt.mnt_root, copy_flags); 2441 new = copy_tree(old, old->mnt.mnt_root, copy_flags);
@@ -2424,6 +2470,10 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2424 } 2470 }
2425 p = next_mnt(p, old); 2471 p = next_mnt(p, old);
2426 q = next_mnt(q, new); 2472 q = next_mnt(q, new);
2473 if (!q)
2474 break;
2475 while (p->mnt.mnt_root != q->mnt.mnt_root)
2476 p = next_mnt(p, old);
2427 } 2477 }
2428 namespace_unlock(); 2478 namespace_unlock();
2429 2479
@@ -2630,6 +2680,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2630 goto out4; 2680 goto out4;
2631 if (!check_mnt(root_mnt) || !check_mnt(new_mnt)) 2681 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
2632 goto out4; 2682 goto out4;
2683 if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
2684 goto out4;
2633 error = -ENOENT; 2685 error = -ENOENT;
2634 if (d_unlinked(new.dentry)) 2686 if (d_unlinked(new.dentry))
2635 goto out4; 2687 goto out4;
@@ -2653,6 +2705,10 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2653 br_write_lock(&vfsmount_lock); 2705 br_write_lock(&vfsmount_lock);
2654 detach_mnt(new_mnt, &parent_path); 2706 detach_mnt(new_mnt, &parent_path);
2655 detach_mnt(root_mnt, &root_parent); 2707 detach_mnt(root_mnt, &root_parent);
2708 if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
2709 new_mnt->mnt.mnt_flags |= MNT_LOCKED;
2710 root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
2711 }
2656 /* mount old root on put_old */ 2712 /* mount old root on put_old */
2657 attach_mnt(root_mnt, old_mnt, old_mp); 2713 attach_mnt(root_mnt, old_mnt, old_mp);
2658 /* mount new_root on / */ 2714 /* mount new_root on / */
@@ -2811,25 +2867,38 @@ bool current_chrooted(void)
2811 return chrooted; 2867 return chrooted;
2812} 2868}
2813 2869
2814void update_mnt_policy(struct user_namespace *userns) 2870bool fs_fully_visible(struct file_system_type *type)
2815{ 2871{
2816 struct mnt_namespace *ns = current->nsproxy->mnt_ns; 2872 struct mnt_namespace *ns = current->nsproxy->mnt_ns;
2817 struct mount *mnt; 2873 struct mount *mnt;
2874 bool visible = false;
2818 2875
2819 down_read(&namespace_sem); 2876 if (unlikely(!ns))
2877 return false;
2878
2879 namespace_lock();
2820 list_for_each_entry(mnt, &ns->list, mnt_list) { 2880 list_for_each_entry(mnt, &ns->list, mnt_list) {
2821 switch (mnt->mnt.mnt_sb->s_magic) { 2881 struct mount *child;
2822 case SYSFS_MAGIC: 2882 if (mnt->mnt.mnt_sb->s_type != type)
2823 userns->may_mount_sysfs = true; 2883 continue;
2824 break; 2884
2825 case PROC_SUPER_MAGIC: 2885 /* This mount is not fully visible if there are any child mounts
2826 userns->may_mount_proc = true; 2886 * that cover anything except for empty directories.
2827 break; 2887 */
2888 list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
2889 struct inode *inode = child->mnt_mountpoint->d_inode;
2890 if (!S_ISDIR(inode->i_mode))
2891 goto next;
2892 if (inode->i_nlink != 2)
2893 goto next;
2828 } 2894 }
2829 if (userns->may_mount_sysfs && userns->may_mount_proc) 2895 visible = true;
2830 break; 2896 goto found;
2897 next: ;
2831 } 2898 }
2832 up_read(&namespace_sem); 2899found:
2900 namespace_unlock();
2901 return visible;
2833} 2902}
2834 2903
2835static void *mntns_get(struct task_struct *task) 2904static void *mntns_get(struct task_struct *task)
@@ -2860,8 +2929,8 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns)
2860 struct path root; 2929 struct path root;
2861 2930
2862 if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || 2931 if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
2863 !nsown_capable(CAP_SYS_CHROOT) || 2932 !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
2864 !nsown_capable(CAP_SYS_ADMIN)) 2933 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
2865 return -EPERM; 2934 return -EPERM;
2866 2935
2867 if (fs->users != 1) 2936 if (fs->users != 1)
diff --git a/fs/open.c b/fs/open.c
index 8070825b285b..2a731b0d08bc 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -443,7 +443,7 @@ retry:
443 goto dput_and_out; 443 goto dput_and_out;
444 444
445 error = -EPERM; 445 error = -EPERM;
446 if (!nsown_capable(CAP_SYS_CHROOT)) 446 if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
447 goto dput_and_out; 447 goto dput_and_out;
448 error = security_path_chroot(&path); 448 error = security_path_chroot(&path);
449 if (error) 449 if (error)
diff --git a/fs/pnode.h b/fs/pnode.h
index b091445c1c4a..59e7eda1851e 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -19,11 +19,14 @@
19 19
20#define CL_EXPIRE 0x01 20#define CL_EXPIRE 0x01
21#define CL_SLAVE 0x02 21#define CL_SLAVE 0x02
22#define CL_COPY_ALL 0x04 22#define CL_COPY_UNBINDABLE 0x04
23#define CL_MAKE_SHARED 0x08 23#define CL_MAKE_SHARED 0x08
24#define CL_PRIVATE 0x10 24#define CL_PRIVATE 0x10
25#define CL_SHARED_TO_SLAVE 0x20 25#define CL_SHARED_TO_SLAVE 0x20
26#define CL_UNPRIVILEGED 0x40 26#define CL_UNPRIVILEGED 0x40
27#define CL_COPY_MNT_NS_FILE 0x80
28
29#define CL_COPY_ALL (CL_COPY_UNBINDABLE | CL_COPY_MNT_NS_FILE)
27 30
28static inline void set_mnt_shared(struct mount *mnt) 31static inline void set_mnt_shared(struct mount *mnt)
29{ 32{
diff --git a/fs/proc/root.c b/fs/proc/root.c
index e0a790da726d..87dbcbef7fe4 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -110,7 +110,11 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
110 ns = task_active_pid_ns(current); 110 ns = task_active_pid_ns(current);
111 options = data; 111 options = data;
112 112
113 if (!current_user_ns()->may_mount_proc) 113 if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
114 return ERR_PTR(-EPERM);
115
116 /* Does the mounter have privilege over the pid namespace? */
117 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
114 return ERR_PTR(-EPERM); 118 return ERR_PTR(-EPERM);
115 } 119 }
116 120
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index fd7ce7a39f91..834ec2cdb7a3 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -112,8 +112,15 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
112 struct super_block *sb; 112 struct super_block *sb;
113 int error; 113 int error;
114 114
115 if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs) 115 if (!(flags & MS_KERNMOUNT)) {
116 return ERR_PTR(-EPERM); 116 if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
117 return ERR_PTR(-EPERM);
118
119 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
120 if (!kobj_ns_current_may_mount(type))
121 return ERR_PTR(-EPERM);
122 }
123 }
117 124
118 info = kzalloc(sizeof(*info), GFP_KERNEL); 125 info = kzalloc(sizeof(*info), GFP_KERNEL);
119 if (!info) 126 if (!info)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index d9a4f7f40f32..a6ee1f9a5018 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -210,7 +210,6 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
210 struct user_namespace *ns, int cap); 210 struct user_namespace *ns, int cap);
211extern bool capable(int cap); 211extern bool capable(int cap);
212extern bool ns_capable(struct user_namespace *ns, int cap); 212extern bool ns_capable(struct user_namespace *ns, int cap);
213extern bool nsown_capable(int cap);
214extern bool inode_capable(const struct inode *inode, int cap); 213extern bool inode_capable(const struct inode *inode, int cap);
215extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); 214extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
216 215
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3b4cd8296e41..529d8711baba 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1900,6 +1900,7 @@ extern int vfs_ustat(dev_t, struct kstatfs *);
1900extern int freeze_super(struct super_block *super); 1900extern int freeze_super(struct super_block *super);
1901extern int thaw_super(struct super_block *super); 1901extern int thaw_super(struct super_block *super);
1902extern bool our_mnt(struct vfsmount *mnt); 1902extern bool our_mnt(struct vfsmount *mnt);
1903extern bool fs_fully_visible(struct file_system_type *);
1903 1904
1904extern int current_umask(void); 1905extern int current_umask(void);
1905 1906
diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h
index f66b065a8b5f..df32d2508290 100644
--- a/include/linux/kobject_ns.h
+++ b/include/linux/kobject_ns.h
@@ -39,6 +39,7 @@ enum kobj_ns_type {
39 */ 39 */
40struct kobj_ns_type_operations { 40struct kobj_ns_type_operations {
41 enum kobj_ns_type type; 41 enum kobj_ns_type type;
42 bool (*current_may_mount)(void);
42 void *(*grab_current_ns)(void); 43 void *(*grab_current_ns)(void);
43 const void *(*netlink_ns)(struct sock *sk); 44 const void *(*netlink_ns)(struct sock *sk);
44 const void *(*initial_ns)(void); 45 const void *(*initial_ns)(void);
@@ -50,6 +51,7 @@ int kobj_ns_type_registered(enum kobj_ns_type type);
50const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); 51const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
51const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); 52const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
52 53
54bool kobj_ns_current_may_mount(enum kobj_ns_type type);
53void *kobj_ns_grab_current(enum kobj_ns_type type); 55void *kobj_ns_grab_current(enum kobj_ns_type type);
54const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk); 56const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
55const void *kobj_ns_initial(enum kobj_ns_type type); 57const void *kobj_ns_initial(enum kobj_ns_type type);
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 73005f9957ea..38cd98f112a0 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -48,6 +48,7 @@ struct mnt_namespace;
48#define MNT_INTERNAL 0x4000 48#define MNT_INTERNAL 0x4000
49 49
50#define MNT_LOCK_READONLY 0x400000 50#define MNT_LOCK_READONLY 0x400000
51#define MNT_LOCKED 0x800000
51 52
52struct vfsmount { 53struct vfsmount {
53 struct dentry *mnt_root; /* root of the mounted tree */ 54 struct dentry *mnt_root; /* root of the mounted tree */
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 14105c26a836..4db29859464f 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -27,8 +27,6 @@ struct user_namespace {
27 kuid_t owner; 27 kuid_t owner;
28 kgid_t group; 28 kgid_t group;
29 unsigned int proc_inum; 29 unsigned int proc_inum;
30 bool may_mount_sysfs;
31 bool may_mount_proc;
32}; 30};
33 31
34extern struct user_namespace init_user_ns; 32extern struct user_namespace init_user_ns;
@@ -85,6 +83,4 @@ static inline void put_user_ns(struct user_namespace *ns)
85 83
86#endif 84#endif
87 85
88void update_mnt_policy(struct user_namespace *userns);
89
90#endif /* _LINUX_USER_H */ 86#endif /* _LINUX_USER_H */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 7ee61bf44933..4be6581d3b7f 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -171,7 +171,7 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new)
171{ 171{
172 struct ipc_namespace *ns = new; 172 struct ipc_namespace *ns = new;
173 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || 173 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
174 !nsown_capable(CAP_SYS_ADMIN)) 174 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
175 return -EPERM; 175 return -EPERM;
176 176
177 /* Ditch state from the old ipc namespace */ 177 /* Ditch state from the old ipc namespace */
diff --git a/kernel/capability.c b/kernel/capability.c
index f6c2ce5701e1..6fc1c8af44df 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -433,18 +433,6 @@ bool capable(int cap)
433EXPORT_SYMBOL(capable); 433EXPORT_SYMBOL(capable);
434 434
435/** 435/**
436 * nsown_capable - Check superior capability to one's own user_ns
437 * @cap: The capability in question
438 *
439 * Return true if the current task has the given superior capability
440 * targeted at its own user namespace.
441 */
442bool nsown_capable(int cap)
443{
444 return ns_capable(current_user_ns(), cap);
445}
446
447/**
448 * inode_capable - Check superior capability over inode 436 * inode_capable - Check superior capability over inode
449 * @inode: The inode in question 437 * @inode: The inode in question
450 * @cap: The capability in question 438 * @cap: The capability in question
diff --git a/kernel/fork.c b/kernel/fork.c
index bf46287c91a4..c9eaf2013002 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1825,11 +1825,6 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1825 if (unshare_flags & CLONE_NEWUSER) 1825 if (unshare_flags & CLONE_NEWUSER)
1826 unshare_flags |= CLONE_THREAD | CLONE_FS; 1826 unshare_flags |= CLONE_THREAD | CLONE_FS;
1827 /* 1827 /*
1828 * If unsharing a pid namespace must also unshare the thread.
1829 */
1830 if (unshare_flags & CLONE_NEWPID)
1831 unshare_flags |= CLONE_THREAD;
1832 /*
1833 * If unsharing a thread from a thread group, must also unshare vm. 1828 * If unsharing a thread from a thread group, must also unshare vm.
1834 */ 1829 */
1835 if (unshare_flags & CLONE_THREAD) 1830 if (unshare_flags & CLONE_THREAD)
diff --git a/kernel/groups.c b/kernel/groups.c
index 6b2588dd04ff..90cf1c38c8ea 100644
--- a/kernel/groups.c
+++ b/kernel/groups.c
@@ -233,7 +233,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist)
233 struct group_info *group_info; 233 struct group_info *group_info;
234 int retval; 234 int retval;
235 235
236 if (!nsown_capable(CAP_SETGID)) 236 if (!ns_capable(current_user_ns(), CAP_SETGID))
237 return -EPERM; 237 return -EPERM;
238 if ((unsigned)gidsetsize > NGROUPS_MAX) 238 if ((unsigned)gidsetsize > NGROUPS_MAX)
239 return -EINVAL; 239 return -EINVAL;
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 997cbb951a3b..8e7811086b82 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -126,22 +126,16 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
126 struct nsproxy *old_ns = tsk->nsproxy; 126 struct nsproxy *old_ns = tsk->nsproxy;
127 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); 127 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
128 struct nsproxy *new_ns; 128 struct nsproxy *new_ns;
129 int err = 0;
130 129
131 if (!old_ns) 130 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
131 CLONE_NEWPID | CLONE_NEWNET)))) {
132 get_nsproxy(old_ns);
132 return 0; 133 return 0;
133
134 get_nsproxy(old_ns);
135
136 if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
137 CLONE_NEWPID | CLONE_NEWNET)))
138 return 0;
139
140 if (!ns_capable(user_ns, CAP_SYS_ADMIN)) {
141 err = -EPERM;
142 goto out;
143 } 134 }
144 135
136 if (!ns_capable(user_ns, CAP_SYS_ADMIN))
137 return -EPERM;
138
145 /* 139 /*
146 * CLONE_NEWIPC must detach from the undolist: after switching 140 * CLONE_NEWIPC must detach from the undolist: after switching
147 * to a new ipc namespace, the semaphore arrays from the old 141 * to a new ipc namespace, the semaphore arrays from the old
@@ -149,22 +143,16 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
149 * means share undolist with parent, so we must forbid using 143 * means share undolist with parent, so we must forbid using
150 * it along with CLONE_NEWIPC. 144 * it along with CLONE_NEWIPC.
151 */ 145 */
152 if ((flags & CLONE_NEWIPC) && (flags & CLONE_SYSVSEM)) { 146 if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) ==
153 err = -EINVAL; 147 (CLONE_NEWIPC | CLONE_SYSVSEM))
154 goto out; 148 return -EINVAL;
155 }
156 149
157 new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); 150 new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs);
158 if (IS_ERR(new_ns)) { 151 if (IS_ERR(new_ns))
159 err = PTR_ERR(new_ns); 152 return PTR_ERR(new_ns);
160 goto out;
161 }
162 153
163 tsk->nsproxy = new_ns; 154 tsk->nsproxy = new_ns;
164 155 return 0;
165out:
166 put_nsproxy(old_ns);
167 return err;
168} 156}
169 157
170void free_nsproxy(struct nsproxy *ns) 158void free_nsproxy(struct nsproxy *ns)
diff --git a/kernel/pid.c b/kernel/pid.c
index 66505c1dfc51..ebe5e80b10f8 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -265,6 +265,7 @@ void free_pid(struct pid *pid)
265 struct pid_namespace *ns = upid->ns; 265 struct pid_namespace *ns = upid->ns;
266 hlist_del_rcu(&upid->pid_chain); 266 hlist_del_rcu(&upid->pid_chain);
267 switch(--ns->nr_hashed) { 267 switch(--ns->nr_hashed) {
268 case 2:
268 case 1: 269 case 1:
269 /* When all that is left in the pid namespace 270 /* When all that is left in the pid namespace
270 * is the reaper wake up the reaper. The reaper 271 * is the reaper wake up the reaper. The reaper
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 601bb361c235..42086551a24a 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -329,7 +329,7 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns)
329 struct pid_namespace *ancestor, *new = ns; 329 struct pid_namespace *ancestor, *new = ns;
330 330
331 if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) || 331 if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) ||
332 !nsown_capable(CAP_SYS_ADMIN)) 332 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
333 return -EPERM; 333 return -EPERM;
334 334
335 /* 335 /*
diff --git a/kernel/sys.c b/kernel/sys.c
index 771129b299f8..c18ecca575b4 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -337,7 +337,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
337 if (rgid != (gid_t) -1) { 337 if (rgid != (gid_t) -1) {
338 if (gid_eq(old->gid, krgid) || 338 if (gid_eq(old->gid, krgid) ||
339 gid_eq(old->egid, krgid) || 339 gid_eq(old->egid, krgid) ||
340 nsown_capable(CAP_SETGID)) 340 ns_capable(old->user_ns, CAP_SETGID))
341 new->gid = krgid; 341 new->gid = krgid;
342 else 342 else
343 goto error; 343 goto error;
@@ -346,7 +346,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
346 if (gid_eq(old->gid, kegid) || 346 if (gid_eq(old->gid, kegid) ||
347 gid_eq(old->egid, kegid) || 347 gid_eq(old->egid, kegid) ||
348 gid_eq(old->sgid, kegid) || 348 gid_eq(old->sgid, kegid) ||
349 nsown_capable(CAP_SETGID)) 349 ns_capable(old->user_ns, CAP_SETGID))
350 new->egid = kegid; 350 new->egid = kegid;
351 else 351 else
352 goto error; 352 goto error;
@@ -387,7 +387,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
387 old = current_cred(); 387 old = current_cred();
388 388
389 retval = -EPERM; 389 retval = -EPERM;
390 if (nsown_capable(CAP_SETGID)) 390 if (ns_capable(old->user_ns, CAP_SETGID))
391 new->gid = new->egid = new->sgid = new->fsgid = kgid; 391 new->gid = new->egid = new->sgid = new->fsgid = kgid;
392 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) 392 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
393 new->egid = new->fsgid = kgid; 393 new->egid = new->fsgid = kgid;
@@ -471,7 +471,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
471 new->uid = kruid; 471 new->uid = kruid;
472 if (!uid_eq(old->uid, kruid) && 472 if (!uid_eq(old->uid, kruid) &&
473 !uid_eq(old->euid, kruid) && 473 !uid_eq(old->euid, kruid) &&
474 !nsown_capable(CAP_SETUID)) 474 !ns_capable(old->user_ns, CAP_SETUID))
475 goto error; 475 goto error;
476 } 476 }
477 477
@@ -480,7 +480,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
480 if (!uid_eq(old->uid, keuid) && 480 if (!uid_eq(old->uid, keuid) &&
481 !uid_eq(old->euid, keuid) && 481 !uid_eq(old->euid, keuid) &&
482 !uid_eq(old->suid, keuid) && 482 !uid_eq(old->suid, keuid) &&
483 !nsown_capable(CAP_SETUID)) 483 !ns_capable(old->user_ns, CAP_SETUID))
484 goto error; 484 goto error;
485 } 485 }
486 486
@@ -534,7 +534,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
534 old = current_cred(); 534 old = current_cred();
535 535
536 retval = -EPERM; 536 retval = -EPERM;
537 if (nsown_capable(CAP_SETUID)) { 537 if (ns_capable(old->user_ns, CAP_SETUID)) {
538 new->suid = new->uid = kuid; 538 new->suid = new->uid = kuid;
539 if (!uid_eq(kuid, old->uid)) { 539 if (!uid_eq(kuid, old->uid)) {
540 retval = set_user(new); 540 retval = set_user(new);
@@ -591,7 +591,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
591 old = current_cred(); 591 old = current_cred();
592 592
593 retval = -EPERM; 593 retval = -EPERM;
594 if (!nsown_capable(CAP_SETUID)) { 594 if (!ns_capable(old->user_ns, CAP_SETUID)) {
595 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) && 595 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
596 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid)) 596 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
597 goto error; 597 goto error;
@@ -673,7 +673,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
673 old = current_cred(); 673 old = current_cred();
674 674
675 retval = -EPERM; 675 retval = -EPERM;
676 if (!nsown_capable(CAP_SETGID)) { 676 if (!ns_capable(old->user_ns, CAP_SETGID)) {
677 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) && 677 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
678 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid)) 678 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
679 goto error; 679 goto error;
@@ -744,7 +744,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
744 744
745 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) || 745 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
746 uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) || 746 uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
747 nsown_capable(CAP_SETUID)) { 747 ns_capable(old->user_ns, CAP_SETUID)) {
748 if (!uid_eq(kuid, old->fsuid)) { 748 if (!uid_eq(kuid, old->fsuid)) {
749 new->fsuid = kuid; 749 new->fsuid = kuid;
750 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) 750 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
@@ -783,7 +783,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
783 783
784 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) || 784 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
785 gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) || 785 gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
786 nsown_capable(CAP_SETGID)) { 786 ns_capable(old->user_ns, CAP_SETGID)) {
787 if (!gid_eq(kgid, old->fsgid)) { 787 if (!gid_eq(kgid, old->fsgid)) {
788 new->fsgid = kgid; 788 new->fsgid = kgid;
789 goto change_okay; 789 goto change_okay;
diff --git a/kernel/uid16.c b/kernel/uid16.c
index f6c83d7ef000..602e5bbbceff 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
176 struct group_info *group_info; 176 struct group_info *group_info;
177 int retval; 177 int retval;
178 178
179 if (!nsown_capable(CAP_SETGID)) 179 if (!ns_capable(current_user_ns(), CAP_SETGID))
180 return -EPERM; 180 return -EPERM;
181 if ((unsigned)gidsetsize > NGROUPS_MAX) 181 if ((unsigned)gidsetsize > NGROUPS_MAX)
182 return -EINVAL; 182 return -EINVAL;
diff --git a/kernel/user.c b/kernel/user.c
index 69b4c3d48cde..5bbb91988e69 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -51,8 +51,6 @@ struct user_namespace init_user_ns = {
51 .owner = GLOBAL_ROOT_UID, 51 .owner = GLOBAL_ROOT_UID,
52 .group = GLOBAL_ROOT_GID, 52 .group = GLOBAL_ROOT_GID,
53 .proc_inum = PROC_USER_INIT_INO, 53 .proc_inum = PROC_USER_INIT_INO,
54 .may_mount_sysfs = true,
55 .may_mount_proc = true,
56}; 54};
57EXPORT_SYMBOL_GPL(init_user_ns); 55EXPORT_SYMBOL_GPL(init_user_ns);
58 56
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 9064b919a406..13fb1134ba58 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -101,8 +101,6 @@ int create_user_ns(struct cred *new)
101 101
102 set_cred_user_ns(new, ns); 102 set_cred_user_ns(new, ns);
103 103
104 update_mnt_policy(ns);
105
106 return 0; 104 return 0;
107} 105}
108 106
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 2fc8576efaa8..fd393124e507 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -114,7 +114,7 @@ static int utsns_install(struct nsproxy *nsproxy, void *new)
114 struct uts_namespace *ns = new; 114 struct uts_namespace *ns = new;
115 115
116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || 116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
117 !nsown_capable(CAP_SYS_ADMIN)) 117 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
118 return -EPERM; 118 return -EPERM;
119 119
120 get_uts_ns(ns); 120 get_uts_ns(ns);
diff --git a/lib/kobject.c b/lib/kobject.c
index 1d46c151a4ae..962175134702 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -931,6 +931,21 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
931 return kobj_child_ns_ops(kobj->parent); 931 return kobj_child_ns_ops(kobj->parent);
932} 932}
933 933
934bool kobj_ns_current_may_mount(enum kobj_ns_type type)
935{
936 bool may_mount = false;
937
938 if (type == KOBJ_NS_TYPE_NONE)
939 return true;
940
941 spin_lock(&kobj_ns_type_lock);
942 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
943 kobj_ns_ops_tbl[type])
944 may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
945 spin_unlock(&kobj_ns_type_lock);
946
947 return may_mount;
948}
934 949
935void *kobj_ns_grab_current(enum kobj_ns_type type) 950void *kobj_ns_grab_current(enum kobj_ns_type type)
936{ 951{
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 3f40ea9de814..d954b56b4e47 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1196,6 +1196,13 @@ static void remove_queue_kobjects(struct net_device *net)
1196#endif 1196#endif
1197} 1197}
1198 1198
1199static bool net_current_may_mount(void)
1200{
1201 struct net *net = current->nsproxy->net_ns;
1202
1203 return ns_capable(net->user_ns, CAP_SYS_ADMIN);
1204}
1205
1199static void *net_grab_current_ns(void) 1206static void *net_grab_current_ns(void)
1200{ 1207{
1201 struct net *ns = current->nsproxy->net_ns; 1208 struct net *ns = current->nsproxy->net_ns;
@@ -1218,6 +1225,7 @@ static const void *net_netlink_ns(struct sock *sk)
1218 1225
1219struct kobj_ns_type_operations net_ns_type_operations = { 1226struct kobj_ns_type_operations net_ns_type_operations = {
1220 .type = KOBJ_NS_TYPE_NET, 1227 .type = KOBJ_NS_TYPE_NET,
1228 .current_may_mount = net_current_may_mount,
1221 .grab_current_ns = net_grab_current_ns, 1229 .grab_current_ns = net_grab_current_ns,
1222 .netlink_ns = net_netlink_ns, 1230 .netlink_ns = net_netlink_ns,
1223 .initial_ns = net_initial_ns, 1231 .initial_ns = net_initial_ns,
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index f97652036754..81d3a9a08453 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -651,7 +651,7 @@ static int netns_install(struct nsproxy *nsproxy, void *ns)
651 struct net *net = ns; 651 struct net *net = ns;
652 652
653 if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) || 653 if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
654 !nsown_capable(CAP_SYS_ADMIN)) 654 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
655 return -EPERM; 655 return -EPERM;
656 656
657 put_net(nsproxy->net_ns); 657 put_net(nsproxy->net_ns);
diff --git a/net/core/scm.c b/net/core/scm.c
index b4da80b1cc07..b442e7e25e60 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -56,9 +56,9 @@ static __inline__ int scm_check_creds(struct ucred *creds)
56 if ((creds->pid == task_tgid_vnr(current) || 56 if ((creds->pid == task_tgid_vnr(current) ||
57 ns_capable(task_active_pid_ns(current)->user_ns, CAP_SYS_ADMIN)) && 57 ns_capable(task_active_pid_ns(current)->user_ns, CAP_SYS_ADMIN)) &&
58 ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || 58 ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) ||
59 uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) && 59 uid_eq(uid, cred->suid)) || ns_capable(cred->user_ns, CAP_SETUID)) &&
60 ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || 60 ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) ||
61 gid_eq(gid, cred->sgid)) || nsown_capable(CAP_SETGID))) { 61 gid_eq(gid, cred->sgid)) || ns_capable(cred->user_ns, CAP_SETGID))) {
62 return 0; 62 return 0;
63 } 63 }
64 return -EPERM; 64 return -EPERM;
diff --git a/security/commoncap.c b/security/commoncap.c
index c44b6fe6648e..b9d613e0ef14 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -768,16 +768,16 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
768 */ 768 */
769static int cap_safe_nice(struct task_struct *p) 769static int cap_safe_nice(struct task_struct *p)
770{ 770{
771 int is_subset; 771 int is_subset, ret = 0;
772 772
773 rcu_read_lock(); 773 rcu_read_lock();
774 is_subset = cap_issubset(__task_cred(p)->cap_permitted, 774 is_subset = cap_issubset(__task_cred(p)->cap_permitted,
775 current_cred()->cap_permitted); 775 current_cred()->cap_permitted);
776 if (!is_subset && !ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE))
777 ret = -EPERM;
776 rcu_read_unlock(); 778 rcu_read_unlock();
777 779
778 if (!is_subset && !capable(CAP_SYS_NICE)) 780 return ret;
779 return -EPERM;
780 return 0;
781} 781}
782 782
783/** 783/**
@@ -824,7 +824,7 @@ int cap_task_setnice(struct task_struct *p, int nice)
824 */ 824 */
825static long cap_prctl_drop(struct cred *new, unsigned long cap) 825static long cap_prctl_drop(struct cred *new, unsigned long cap)
826{ 826{
827 if (!capable(CAP_SETPCAP)) 827 if (!ns_capable(current_user_ns(), CAP_SETPCAP))
828 return -EPERM; 828 return -EPERM;
829 if (!cap_valid(cap)) 829 if (!cap_valid(cap))
830 return -EINVAL; 830 return -EINVAL;