History

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull namespace changes from Eric Biederman: "This is an assorted mishmash of small cleanups, enhancements and bug fixes. The major theme is user namespace mount restrictions. nsown_capable is killed as it encourages not thinking about details that need to be considered. A very hard to hit pid namespace exiting bug was finally tracked and fixed. A couple of cleanups to the basic namespace infrastructure. Finally there is an enhancement that makes per user namespace capabilities usable as capabilities, and an enhancement that allows the per userns root to nice other processes in the user namespace" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: userns: Kill nsown_capable it makes the wrong thing easy capabilities: allow nice if we are privileged pidns: Don't have unshare(CLONE_NEWPID) imply CLONE_THREAD userns: Allow PR_CAPBSET_DROP in a user namespace. namespaces: Simplify copy_namespaces so it is clear what is going on. pidns: Fix hang in zap_pid_ns_processes by sending a potentially extra wakeup sysfs: Restrict mounting sysfs userns: Better restrictions on when proc and sysfs can be mounted vfs: Don't copy mount bind mounts of /proc/<pid>/ns/mnt between namespaces kernel/nsproxy.c: Improving a snippet of code. proc: Restrict mounting the proc filesystem vfs: Lock in place mounts from more privileged users

Linus Torvalds committed 13 years ago

Commit c7c45912 parents 11c7b03 c7b96ac27 files · +177 −104Browse files

Unified · Split

27 files
  1. fs/namespace.c +95 −26
  2. fs/open.c +1 −1
  3. fs/pnode.h +4 −1
  4. fs/proc/root.c +5 −1
  5. fs/sysfs/mount.c +9 −2
  6. include/linux/capability.h +0 −1
  7. include/linux/fs.h +1 −0
  8. include/linux/kobject_ns.h +2 −0
  9. include/linux/mount.h +1 −0
  10. include/linux/user_namespace.h +0 −4
  11. ipc/namespace.c +1 −1
  12. kernel/capability.c +0 −12
  13. kernel/fork.c +0 −5
  14. kernel/groups.c +1 −1
  15. kernel/nsproxy.c +12 −24
  16. kernel/pid.c +1 −0
  17. kernel/pid_namespace.c +1 −1
  18. kernel/sys.c +10 −10
  19. kernel/uid16.c +1 −1
  20. kernel/user.c +0 −2
  21. kernel/user_namespace.c +0 −2
  22. kernel/utsname.c +1 −1
  23. lib/kobject.c +15 −0
  24. net/core/net-sysfs.c +8 −0
  25. net/core/net_namespace.c +1 −1
  26. net/core/scm.c +2 −2
  27. security/commoncap.c +5 −5
fs/namespace.c+95−26
@@ -831,6 +831,10 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, · 830 unmodified lines
831831 if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY))
832832 mnt->mnt.mnt_flags |= MNT_LOCK_READONLY;
833833
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+
834838 atomic_inc(&sb->s_active);
835839 mnt->mnt.mnt_sb = sb;
836840 mnt->mnt.mnt_root = dget(root);
@@ -1327,6 +1331,8 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) · 490 unmodified lines
13271331 goto dput_and_out;
13281332 if (!check_mnt(mnt))
13291333 goto dput_and_out;
1334+ if (mnt->mnt.mnt_flags & MNT_LOCKED)
1335+ goto dput_and_out;
13301336
13311337 retval = do_umount(mnt, flags);
13321338 dput_and_out:
@@ -1349,14 +1355,11 @@ SYSCALL_DEFINE1(oldumount, char __user *, name) · 16 unmodified lines
13491355
13501356 #endif
13511357
1352−static bool mnt_ns_loop(struct path *path)
1358+static bool is_mnt_ns_file(struct dentry *dentry)
13531359 {
1354− /* Could bind mounting the mount namespace inode cause a
1355− * mount namespace loop?
1356− */
1357− struct inode *inode = path->dentry->d_inode;
1360+ /* Is this a proxy for a mount namespace? */
1361+ struct inode *inode = dentry->d_inode;
13581362 struct proc_ns *ei;
1359− struct mnt_namespace *mnt_ns;
13601363
13611364 if (!proc_ns_inode(inode))
13621365 return false;
@@ -1365,7 +1368,19 @@ static bool mnt_ns_loop(struct path *path) · 2 unmodified lines
13651368 if (ei->ns_ops != &mntns_operations)
13661369 return false;
13671370
1368− mnt_ns = ei->ns;
1371+ return true;
1372+}
1373+
1374+static 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;
13691384 return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;
13701385 }
13711386
@@ -1374,13 +1389,17 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, · 2 unmodified lines
13741389 {
13751390 struct mount *res, *p, *q, *r, *parent;
13761391
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))
13781396 return ERR_PTR(-EINVAL);
13791397
13801398 res = q = clone_mnt(mnt, dentry, flag);
13811399 if (IS_ERR(q))
13821400 return q;
13831401
1402+ q->mnt.mnt_flags &= ~MNT_LOCKED;
13841403 q->mnt_mountpoint = mnt->mnt_mountpoint;
13851404
13861405 p = mnt;
@@ -1390,7 +1409,13 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, · 3 unmodified lines
13901409 continue;
13911410
13921411 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)) {
13941419 s = skip_mnt_tree(s);
13951420 continue;
13961421 }
@@ -1696,6 +1721,19 @@ static int do_change_type(struct path *path, int flag) · 299 unmodified lines
16961721 return err;
16971722 }
16981723
1724+static 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+
16991737 /*
17001738 * do loopback mount.
17011739 */
@@ -1713,7 +1751,7 @@ static int do_loopback(struct path *path, const char *old_name, · 11 unmodified lines
17131751 return err;
17141752
17151753 err = -EINVAL;
1716− if (mnt_ns_loop(&old_path))
1754+ if (mnt_ns_loop(old_path.dentry))
17171755 goto out;
17181756
17191757 mp = lock_mount(path);
@@ -1731,8 +1769,11 @@ static int do_loopback(struct path *path, const char *old_name, · 11 unmodified lines
17311769 if (!check_mnt(parent) || !check_mnt(old))
17321770 goto out2;
17331771
1772+ if (!recurse && has_locked_children(old, old_path.dentry))
1773+ goto out2;
1774+
17341775 if (recurse)
1735− mnt = copy_tree(old, old_path.dentry, 0);
1776+ mnt = copy_tree(old, old_path.dentry, CL_COPY_MNT_NS_FILE);
17361777 else
17371778 mnt = clone_mnt(old, old_path.dentry, 0);
17381779
@@ -1741,6 +1782,8 @@ static int do_loopback(struct path *path, const char *old_name, · 2 unmodified lines
17411782 goto out2;
17421783 }
17431784
1785+ mnt->mnt.mnt_flags &= ~MNT_LOCKED;
1786+
17441787 err = graft_tree(mnt, parent, mp);
17451788 if (err) {
17461789 br_write_lock(&vfsmount_lock);
@@ -1853,6 +1896,9 @@ static int do_move_mount(struct path *path, const char *old_name) · 106 unmodified lines
18531896 if (!check_mnt(p) || !check_mnt(old))
18541897 goto out1;
18551898
1899+ if (old->mnt.mnt_flags & MNT_LOCKED)
1900+ goto out1;
1901+
18561902 err = -EINVAL;
18571903 if (old_path.dentry != old_path.mnt->mnt_root)
18581904 goto out1;
@@ -2389,7 +2435,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, · 530 unmodified lines
23892435
23902436 namespace_lock();
23912437 /* First pass: copy the tree topology */
2392− copy_flags = CL_COPY_ALL | CL_EXPIRE;
2438+ copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
23932439 if (user_ns != mnt_ns->user_ns)
23942440 copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED;
23952441 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, · 28 unmodified lines
24242470 }
24252471 p = next_mnt(p, old);
24262472 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);
24272477 }
24282478 namespace_unlock();
24292479
@@ -2630,6 +2680,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, · 200 unmodified lines
26302680 goto out4;
26312681 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
26322682 goto out4;
2683+ if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
2684+ goto out4;
26332685 error = -ENOENT;
26342686 if (d_unlinked(new.dentry))
26352687 goto out4;
@@ -2653,6 +2705,10 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, · 17 unmodified lines
26532705 br_write_lock(&vfsmount_lock);
26542706 detach_mnt(new_mnt, &parent_path);
26552707 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+ }
26562712 /* mount old root on put_old */
26572713 attach_mnt(root_mnt, old_mnt, old_mp);
26582714 /* mount new_root on / */
@@ -2811,25 +2867,38 @@ bool current_chrooted(void) · 152 unmodified lines
28112867 return chrooted;
28122868 }
28132869
2814−void update_mnt_policy(struct user_namespace *userns)
2870+bool fs_fully_visible(struct file_system_type *type)
28152871 {
28162872 struct mnt_namespace *ns = current->nsproxy->mnt_ns;
28172873 struct mount *mnt;
2874+ bool visible = false;
28182875
2819− down_read(&namespace_sem);
2876+ if (unlikely(!ns))
2877+ return false;
2878+
2879+ namespace_lock();
28202880 list_for_each_entry(mnt, &ns->list, mnt_list) {
2821− switch (mnt->mnt.mnt_sb->s_magic) {
2822− case SYSFS_MAGIC:
2823− userns->may_mount_sysfs = true;
2824− break;
2825− case PROC_SUPER_MAGIC:
2826− userns->may_mount_proc = true;
2827− break;
2881+ struct mount *child;
2882+ if (mnt->mnt.mnt_sb->s_type != type)
2883+ continue;
2884+
2885+ /* This mount is not fully visible if there are any child mounts
2886+ * that cover anything except for empty directories.
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;
28282894 }
2829− if (userns->may_mount_sysfs && userns->may_mount_proc)
2830− break;
2895+ visible = true;
2896+ goto found;
2897+ next: ;
28312898 }
2832− up_read(&namespace_sem);
2899+found:
2900+ namespace_unlock();
2901+ return visible;
28332902 }
28342903
28352904 static void *mntns_get(struct task_struct *task)
@@ -2860,8 +2929,8 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) · 24 unmodified lines
28602929 struct path root;
28612930
28622931 if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
2863− !nsown_capable(CAP_SYS_CHROOT) ||
2864− !nsown_capable(CAP_SYS_ADMIN))
2932+ !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
2933+ !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
28652934 return -EPERM;
28662935
28672936 if (fs->users != 1)
fs/open.c+1−1
@@ -443,7 +443,7 @@ retry: · 442 unmodified lines
443443 goto dput_and_out;
444444
445445 error = -EPERM;
446− if (!nsown_capable(CAP_SYS_CHROOT))
446+ if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
447447 goto dput_and_out;
448448 error = security_path_chroot(&path);
449449 if (error)
fs/pnode.h+4−1
@@ -19,11 +19,14 @@ · 18 unmodified lines
1919
2020 #define CL_EXPIRE 0x01
2121 #define CL_SLAVE 0x02
22−#define CL_COPY_ALL 0x04
22+#define CL_COPY_UNBINDABLE 0x04
2323 #define CL_MAKE_SHARED 0x08
2424 #define CL_PRIVATE 0x10
2525 #define CL_SHARED_TO_SLAVE 0x20
2626 #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)
2730
2831 static inline void set_mnt_shared(struct mount *mnt)
2932 {
fs/proc/root.c+5−1
@@ -110,7 +110,11 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, · 109 unmodified lines
110110 ns = task_active_pid_ns(current);
111111 options = data;
112112
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))
114118 return ERR_PTR(-EPERM);
115119 }
116120
fs/sysfs/mount.c+9−2
@@ -112,8 +112,15 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, · 111 unmodified lines
112112 struct super_block *sb;
113113 int error;
114114
115− if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs)
116− return ERR_PTR(-EPERM);
115+ if (!(flags & MS_KERNMOUNT)) {
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+ }
117124
118125 info = kzalloc(sizeof(*info), GFP_KERNEL);
119126 if (!info)
include/linux/capability.h+0−1
@@ -210,7 +210,6 @@ extern bool has_ns_capability_noaudit(struct task_struct *t, · 209 unmodified lines
210210 struct user_namespace *ns, int cap);
211211 extern bool capable(int cap);
212212 extern bool ns_capable(struct user_namespace *ns, int cap);
213−extern bool nsown_capable(int cap);
214213 extern bool inode_capable(const struct inode *inode, int cap);
215214 extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
216215
include/linux/fs.h+1−0
@@ -1900,6 +1900,7 @@ extern int vfs_ustat(dev_t, struct kstatfs *); · 1899 unmodified lines
19001900 extern int freeze_super(struct super_block *super);
19011901 extern int thaw_super(struct super_block *super);
19021902 extern bool our_mnt(struct vfsmount *mnt);
1903+extern bool fs_fully_visible(struct file_system_type *);
19031904
19041905 extern int current_umask(void);
19051906
include/linux/kobject_ns.h+2−0
@@ -39,6 +39,7 @@ enum kobj_ns_type { · 38 unmodified lines
3939 */
4040 struct kobj_ns_type_operations {
4141 enum kobj_ns_type type;
42+ bool (*current_may_mount)(void);
4243 void *(*grab_current_ns)(void);
4344 const void *(*netlink_ns)(struct sock *sk);
4445 const void *(*initial_ns)(void);
@@ -50,6 +51,7 @@ int kobj_ns_type_registered(enum kobj_ns_type type); · 5 unmodified lines
5051 const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
5152 const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
5253
54+bool kobj_ns_current_may_mount(enum kobj_ns_type type);
5355 void *kobj_ns_grab_current(enum kobj_ns_type type);
5456 const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
5557 const void *kobj_ns_initial(enum kobj_ns_type type);
include/linux/mount.h+1−0
@@ -48,6 +48,7 @@ struct mnt_namespace; · 47 unmodified lines
4848 #define MNT_INTERNAL 0x4000
4949
5050 #define MNT_LOCK_READONLY 0x400000
51+#define MNT_LOCKED 0x800000
5152
5253 struct vfsmount {
5354 struct dentry *mnt_root; /* root of the mounted tree */
include/linux/user_namespace.h+0−4
@@ -27,8 +27,6 @@ struct user_namespace { · 26 unmodified lines
2727 kuid_t owner;
2828 kgid_t group;
2929 unsigned int proc_inum;
30− bool may_mount_sysfs;
31− bool may_mount_proc;
3230 };
3331
3432 extern struct user_namespace init_user_ns;
@@ -85,6 +83,4 @@ static inline void put_user_ns(struct user_namespace *ns) · 50 unmodified lines
8583
8684 #endif
8785
88−void update_mnt_policy(struct user_namespace *userns);
89−
9086 #endif /* _LINUX_USER_H */
ipc/namespace.c+1−1
@@ -171,7 +171,7 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new) · 170 unmodified lines
171171 {
172172 struct ipc_namespace *ns = new;
173173 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
174− !nsown_capable(CAP_SYS_ADMIN))
174+ !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
175175 return -EPERM;
176176
177177 /* Ditch state from the old ipc namespace */
kernel/capability.c+0−12
@@ -432,18 +432,6 @@ bool capable(int cap) · 431 unmodified lines
432432 }
433433 EXPORT_SYMBOL(capable);
434434
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− */
442−bool nsown_capable(int cap)
443−{
444− return ns_capable(current_user_ns(), cap);
445−}
446−
447435 /**
448436 * inode_capable - Check superior capability over inode
449437 * @inode: The inode in question
kernel/fork.c+0−5
@@ -1824,11 +1824,6 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) · 1823 unmodified lines
18241824 */
18251825 if (unshare_flags & CLONE_NEWUSER)
18261826 unshare_flags |= CLONE_THREAD | CLONE_FS;
1827− /*
1828− * If unsharing a pid namespace must also unshare the thread.
1829− */
1830− if (unshare_flags & CLONE_NEWPID)
1831− unshare_flags |= CLONE_THREAD;
18321827 /*
18331828 * If unsharing a thread from a thread group, must also unshare vm.
18341829 */
kernel/groups.c+1−1
@@ -233,7 +233,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) · 232 unmodified lines
233233 struct group_info *group_info;
234234 int retval;
235235
236− if (!nsown_capable(CAP_SETGID))
236+ if (!ns_capable(current_user_ns(), CAP_SETGID))
237237 return -EPERM;
238238 if ((unsigned)gidsetsize > NGROUPS_MAX)
239239 return -EINVAL;
kernel/nsproxy.c+12−24
@@ -126,22 +126,16 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) · 125 unmodified lines
126126 struct nsproxy *old_ns = tsk->nsproxy;
127127 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
128128 struct nsproxy *new_ns;
129− int err = 0;
130129
131− if (!old_ns)
130+ if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
131+ CLONE_NEWPID | CLONE_NEWNET)))) {
132+ get_nsproxy(old_ns);
132133 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;
143134 }
144135
136+ if (!ns_capable(user_ns, CAP_SYS_ADMIN))
137+ return -EPERM;
138+
145139 /*
146140 * CLONE_NEWIPC must detach from the undolist: after switching
147141 * 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) · 1 unmodified line
149143 * means share undolist with parent, so we must forbid using
150144 * it along with CLONE_NEWIPC.
151145 */
152− if ((flags & CLONE_NEWIPC) && (flags & CLONE_SYSVSEM)) {
153− err = -EINVAL;
154− goto out;
155− }
146+ if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) ==
147+ (CLONE_NEWIPC | CLONE_SYSVSEM))
148+ return -EINVAL;
156149
157150 new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs);
158− if (IS_ERR(new_ns)) {
159− err = PTR_ERR(new_ns);
160− goto out;
161− }
151+ if (IS_ERR(new_ns))
152+ return PTR_ERR(new_ns);
162153
163154 tsk->nsproxy = new_ns;
164−
165−out:
166− put_nsproxy(old_ns);
167− return err;
155+ return 0;
168156 }
169157
170158 void free_nsproxy(struct nsproxy *ns)
kernel/pid.c+1−0
@@ -265,6 +265,7 @@ void free_pid(struct pid *pid) · 264 unmodified lines
265265 struct pid_namespace *ns = upid->ns;
266266 hlist_del_rcu(&upid->pid_chain);
267267 switch(--ns->nr_hashed) {
268+ case 2:
268269 case 1:
269270 /* When all that is left in the pid namespace
270271 * is the reaper wake up the reaper. The reaper
kernel/pid_namespace.c+1−1
@@ -329,7 +329,7 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns) · 328 unmodified lines
329329 struct pid_namespace *ancestor, *new = ns;
330330
331331 if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) ||
332− !nsown_capable(CAP_SYS_ADMIN))
332+ !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
333333 return -EPERM;
334334
335335 /*
kernel/sys.c+10−10
@@ -337,7 +337,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) · 336 unmodified lines
337337 if (rgid != (gid_t) -1) {
338338 if (gid_eq(old->gid, krgid) ||
339339 gid_eq(old->egid, krgid) ||
340− nsown_capable(CAP_SETGID))
340+ ns_capable(old->user_ns, CAP_SETGID))
341341 new->gid = krgid;
342342 else
343343 goto error;
@@ -346,7 +346,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) · 2 unmodified lines
346346 if (gid_eq(old->gid, kegid) ||
347347 gid_eq(old->egid, kegid) ||
348348 gid_eq(old->sgid, kegid) ||
349− nsown_capable(CAP_SETGID))
349+ ns_capable(old->user_ns, CAP_SETGID))
350350 new->egid = kegid;
351351 else
352352 goto error;
@@ -387,7 +387,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid) · 34 unmodified lines
387387 old = current_cred();
388388
389389 retval = -EPERM;
390− if (nsown_capable(CAP_SETGID))
390+ if (ns_capable(old->user_ns, CAP_SETGID))
391391 new->gid = new->egid = new->sgid = new->fsgid = kgid;
392392 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
393393 new->egid = new->fsgid = kgid;
@@ -471,7 +471,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) · 77 unmodified lines
471471 new->uid = kruid;
472472 if (!uid_eq(old->uid, kruid) &&
473473 !uid_eq(old->euid, kruid) &&
474− !nsown_capable(CAP_SETUID))
474+ !ns_capable(old->user_ns, CAP_SETUID))
475475 goto error;
476476 }
477477
@@ -480,7 +480,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) · 2 unmodified lines
480480 if (!uid_eq(old->uid, keuid) &&
481481 !uid_eq(old->euid, keuid) &&
482482 !uid_eq(old->suid, keuid) &&
483− !nsown_capable(CAP_SETUID))
483+ !ns_capable(old->user_ns, CAP_SETUID))
484484 goto error;
485485 }
486486
@@ -534,7 +534,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid) · 47 unmodified lines
534534 old = current_cred();
535535
536536 retval = -EPERM;
537− if (nsown_capable(CAP_SETUID)) {
537+ if (ns_capable(old->user_ns, CAP_SETUID)) {
538538 new->suid = new->uid = kuid;
539539 if (!uid_eq(kuid, old->uid)) {
540540 retval = set_user(new);
@@ -591,7 +591,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) · 50 unmodified lines
591591 old = current_cred();
592592
593593 retval = -EPERM;
594− if (!nsown_capable(CAP_SETUID)) {
594+ if (!ns_capable(old->user_ns, CAP_SETUID)) {
595595 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
596596 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
597597 goto error;
@@ -673,7 +673,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) · 75 unmodified lines
673673 old = current_cred();
674674
675675 retval = -EPERM;
676− if (!nsown_capable(CAP_SETGID)) {
676+ if (!ns_capable(old->user_ns, CAP_SETGID)) {
677677 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
678678 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
679679 goto error;
@@ -744,7 +744,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid) · 64 unmodified lines
744744
745745 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
746746 uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
747− nsown_capable(CAP_SETUID)) {
747+ ns_capable(old->user_ns, CAP_SETUID)) {
748748 if (!uid_eq(kuid, old->fsuid)) {
749749 new->fsuid = kuid;
750750 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
@@ -783,7 +783,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid) · 32 unmodified lines
783783
784784 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
785785 gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
786− nsown_capable(CAP_SETGID)) {
786+ ns_capable(old->user_ns, CAP_SETGID)) {
787787 if (!gid_eq(kgid, old->fsgid)) {
788788 new->fsgid = kgid;
789789 goto change_okay;
kernel/uid16.c+1−1
@@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) · 175 unmodified lines
176176 struct group_info *group_info;
177177 int retval;
178178
179− if (!nsown_capable(CAP_SETGID))
179+ if (!ns_capable(current_user_ns(), CAP_SETGID))
180180 return -EPERM;
181181 if ((unsigned)gidsetsize > NGROUPS_MAX)
182182 return -EINVAL;
kernel/user.c+0−2
@@ -51,8 +51,6 @@ struct user_namespace init_user_ns = { · 50 unmodified lines
5151 .owner = GLOBAL_ROOT_UID,
5252 .group = GLOBAL_ROOT_GID,
5353 .proc_inum = PROC_USER_INIT_INO,
54− .may_mount_sysfs = true,
55− .may_mount_proc = true,
5654 };
5755 EXPORT_SYMBOL_GPL(init_user_ns);
5856
kernel/user_namespace.c+0−2
@@ -101,8 +101,6 @@ int create_user_ns(struct cred *new) · 100 unmodified lines
101101
102102 set_cred_user_ns(new, ns);
103103
104− update_mnt_policy(ns);
105−
106104 return 0;
107105 }
108106
kernel/utsname.c+1−1
@@ -114,7 +114,7 @@ static int utsns_install(struct nsproxy *nsproxy, void *new) · 113 unmodified lines
114114 struct uts_namespace *ns = new;
115115
116116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
117− !nsown_capable(CAP_SYS_ADMIN))
117+ !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
118118 return -EPERM;
119119
120120 get_uts_ns(ns);
lib/kobject.c+15−0
@@ -931,6 +931,21 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj) · 930 unmodified lines
931931 return kobj_child_ns_ops(kobj->parent);
932932 }
933933
934+bool 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+}
934949
935950 void *kobj_ns_grab_current(enum kobj_ns_type type)
936951 {
net/core/net-sysfs.c+8−0
@@ -1196,6 +1196,13 @@ static void remove_queue_kobjects(struct net_device *net) · 1195 unmodified lines
11961196 #endif
11971197 }
11981198
1199+static 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+
11991206 static void *net_grab_current_ns(void)
12001207 {
12011208 struct net *ns = current->nsproxy->net_ns;
@@ -1218,6 +1225,7 @@ static const void *net_netlink_ns(struct sock *sk) · 16 unmodified lines
12181225
12191226 struct kobj_ns_type_operations net_ns_type_operations = {
12201227 .type = KOBJ_NS_TYPE_NET,
1228+ .current_may_mount = net_current_may_mount,
12211229 .grab_current_ns = net_grab_current_ns,
12221230 .netlink_ns = net_netlink_ns,
12231231 .initial_ns = net_initial_ns,
net/core/net_namespace.c+1−1
@@ -651,7 +651,7 @@ static int netns_install(struct nsproxy *nsproxy, void *ns) · 650 unmodified lines
651651 struct net *net = ns;
652652
653653 if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
654− !nsown_capable(CAP_SYS_ADMIN))
654+ !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
655655 return -EPERM;
656656
657657 put_net(nsproxy->net_ns);
net/core/scm.c+2−2
@@ -56,9 +56,9 @@ static __inline__ int scm_check_creds(struct ucred *creds) · 55 unmodified lines
5656 if ((creds->pid == task_tgid_vnr(current) ||
5757 ns_capable(task_active_pid_ns(current)->user_ns, CAP_SYS_ADMIN)) &&
5858 ((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)) &&
6060 ((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))) {
6262 return 0;
6363 }
6464 return -EPERM;
security/commoncap.c+5−5
@@ -768,16 +768,16 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags) · 767 unmodified lines
768768 */
769769 static int cap_safe_nice(struct task_struct *p)
770770 {
771− int is_subset;
771+ int is_subset, ret = 0;
772772
773773 rcu_read_lock();
774774 is_subset = cap_issubset(__task_cred(p)->cap_permitted,
775775 current_cred()->cap_permitted);
776+ if (!is_subset && !ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE))
777+ ret = -EPERM;
776778 rcu_read_unlock();
777779
778− if (!is_subset && !capable(CAP_SYS_NICE))
779− return -EPERM;
780− return 0;
780+ return ret;
781781 }
782782
783783 /**
@@ -824,7 +824,7 @@ int cap_task_setnice(struct task_struct *p, int nice) · 40 unmodified lines
824824 */
825825 static long cap_prctl_drop(struct cred *new, unsigned long cap)
826826 {
827− if (!capable(CAP_SETPCAP))
827+ if (!ns_capable(current_user_ns(), CAP_SETPCAP))
828828 return -EPERM;
829829 if (!cap_valid(cap))
830830 return -EINVAL;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t