diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2013-03-20 15:49:49 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2013-08-31 02:44:11 -0400 |
commit | c7b96acf1456ef127fef461fcfedb54b81fecfbb (patch) | |
tree | 1cc9387d23e96685453e545bda6d5a5efea8fa63 | |
parent | f54fb863c6bbcbafdfc332b4a4260abb5a002137 (diff) |
userns: Kill nsown_capable it makes the wrong thing easy
nsown_capable is a special case of ns_capable essentially for just CAP_SETUID and
CAP_SETGID. For the existing users it doesn't noticably simplify things and
from the suggested patches I have seen it encourages people to do the wrong
thing. So remove nsown_capable.
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r-- | fs/namespace.c | 4 | ||||
-rw-r--r-- | fs/open.c | 2 | ||||
-rw-r--r-- | include/linux/capability.h | 1 | ||||
-rw-r--r-- | ipc/namespace.c | 2 | ||||
-rw-r--r-- | kernel/capability.c | 12 | ||||
-rw-r--r-- | kernel/groups.c | 2 | ||||
-rw-r--r-- | kernel/pid_namespace.c | 2 | ||||
-rw-r--r-- | kernel/sys.c | 20 | ||||
-rw-r--r-- | kernel/uid16.c | 2 | ||||
-rw-r--r-- | kernel/utsname.c | 2 | ||||
-rw-r--r-- | net/core/net_namespace.c | 2 | ||||
-rw-r--r-- | net/core/scm.c | 4 |
12 files changed, 21 insertions, 34 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 877e4277f496..dc519a1437ee 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -2929,8 +2929,8 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) | |||
2929 | struct path root; | 2929 | struct path root; |
2930 | 2930 | ||
2931 | if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || | 2931 | if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || |
2932 | !nsown_capable(CAP_SYS_CHROOT) || | 2932 | !ns_capable(current_user_ns(), CAP_SYS_CHROOT) || |
2933 | !nsown_capable(CAP_SYS_ADMIN)) | 2933 | !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) |
2934 | return -EPERM; | 2934 | return -EPERM; |
2935 | 2935 | ||
2936 | if (fs->users != 1) | 2936 | if (fs->users != 1) |
@@ -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/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); |
211 | extern bool capable(int cap); | 211 | extern bool capable(int cap); |
212 | extern bool ns_capable(struct user_namespace *ns, int cap); | 212 | extern bool ns_capable(struct user_namespace *ns, int cap); |
213 | extern bool nsown_capable(int cap); | ||
214 | extern bool inode_capable(const struct inode *inode, int cap); | 213 | extern bool inode_capable(const struct inode *inode, int cap); |
215 | extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); | 214 | extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); |
216 | 215 | ||
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) | |||
433 | EXPORT_SYMBOL(capable); | 433 | EXPORT_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 | */ | ||
442 | bool 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/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/pid_namespace.c b/kernel/pid_namespace.c index 6917e8edb48e..ee1f6bb83d67 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/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/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 03795d0147f2..c346f58d97c2 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(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) && | 57 | ns_capable(current->nsproxy->pid_ns->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; |