Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+21 -34
+2 -2
fs/namespace.c
··· 2929 2929 struct path root; 2930 2930 2931 2931 if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || 2932 - !nsown_capable(CAP_SYS_CHROOT) || 2933 - !nsown_capable(CAP_SYS_ADMIN)) 2932 + !ns_capable(current_user_ns(), CAP_SYS_CHROOT) || 2933 + !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) 2934 2934 return -EPERM; 2935 2935 2936 2936 if (fs->users != 1)
+1 -1
fs/open.c
··· 443 443 goto dput_and_out; 444 444 445 445 error = -EPERM; 446 - if (!nsown_capable(CAP_SYS_CHROOT)) 446 + if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT)) 447 447 goto dput_and_out; 448 448 error = security_path_chroot(&path); 449 449 if (error)
-1
include/linux/capability.h
··· 210 210 struct user_namespace *ns, int cap); 211 211 extern bool capable(int cap); 212 212 extern bool ns_capable(struct user_namespace *ns, int cap); 213 - extern bool nsown_capable(int cap); 214 213 extern bool inode_capable(const struct inode *inode, int cap); 215 214 extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); 216 215
+1 -1
ipc/namespace.c
··· 171 171 { 172 172 struct ipc_namespace *ns = new; 173 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 175 return -EPERM; 176 176 177 177 /* Ditch state from the old ipc namespace */
-12
kernel/capability.c
··· 433 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 436 * inode_capable - Check superior capability over inode 449 437 * @inode: The inode in question 450 438 * @cap: The capability in question
+1 -1
kernel/groups.c
··· 233 233 struct group_info *group_info; 234 234 int retval; 235 235 236 - if (!nsown_capable(CAP_SETGID)) 236 + if (!ns_capable(current_user_ns(), CAP_SETGID)) 237 237 return -EPERM; 238 238 if ((unsigned)gidsetsize > NGROUPS_MAX) 239 239 return -EINVAL;
+1 -1
kernel/pid_namespace.c
··· 329 329 struct pid_namespace *ancestor, *new = ns; 330 330 331 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 333 return -EPERM; 334 334 335 335 /*
+10 -10
kernel/sys.c
··· 337 337 if (rgid != (gid_t) -1) { 338 338 if (gid_eq(old->gid, krgid) || 339 339 gid_eq(old->egid, krgid) || 340 - nsown_capable(CAP_SETGID)) 340 + ns_capable(old->user_ns, CAP_SETGID)) 341 341 new->gid = krgid; 342 342 else 343 343 goto error; ··· 346 346 if (gid_eq(old->gid, kegid) || 347 347 gid_eq(old->egid, kegid) || 348 348 gid_eq(old->sgid, kegid) || 349 - nsown_capable(CAP_SETGID)) 349 + ns_capable(old->user_ns, CAP_SETGID)) 350 350 new->egid = kegid; 351 351 else 352 352 goto error; ··· 387 387 old = current_cred(); 388 388 389 389 retval = -EPERM; 390 - if (nsown_capable(CAP_SETGID)) 390 + if (ns_capable(old->user_ns, CAP_SETGID)) 391 391 new->gid = new->egid = new->sgid = new->fsgid = kgid; 392 392 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) 393 393 new->egid = new->fsgid = kgid; ··· 471 471 new->uid = kruid; 472 472 if (!uid_eq(old->uid, kruid) && 473 473 !uid_eq(old->euid, kruid) && 474 - !nsown_capable(CAP_SETUID)) 474 + !ns_capable(old->user_ns, CAP_SETUID)) 475 475 goto error; 476 476 } 477 477 ··· 480 480 if (!uid_eq(old->uid, keuid) && 481 481 !uid_eq(old->euid, keuid) && 482 482 !uid_eq(old->suid, keuid) && 483 - !nsown_capable(CAP_SETUID)) 483 + !ns_capable(old->user_ns, CAP_SETUID)) 484 484 goto error; 485 485 } 486 486 ··· 534 534 old = current_cred(); 535 535 536 536 retval = -EPERM; 537 - if (nsown_capable(CAP_SETUID)) { 537 + if (ns_capable(old->user_ns, CAP_SETUID)) { 538 538 new->suid = new->uid = kuid; 539 539 if (!uid_eq(kuid, old->uid)) { 540 540 retval = set_user(new); ··· 591 591 old = current_cred(); 592 592 593 593 retval = -EPERM; 594 - if (!nsown_capable(CAP_SETUID)) { 594 + if (!ns_capable(old->user_ns, CAP_SETUID)) { 595 595 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) && 596 596 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid)) 597 597 goto error; ··· 673 673 old = current_cred(); 674 674 675 675 retval = -EPERM; 676 - if (!nsown_capable(CAP_SETGID)) { 676 + if (!ns_capable(old->user_ns, CAP_SETGID)) { 677 677 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) && 678 678 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid)) 679 679 goto error; ··· 744 744 745 745 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) || 746 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 748 if (!uid_eq(kuid, old->fsuid)) { 749 749 new->fsuid = kuid; 750 750 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) ··· 783 783 784 784 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) || 785 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 787 if (!gid_eq(kgid, old->fsgid)) { 788 788 new->fsgid = kgid; 789 789 goto change_okay;
+1 -1
kernel/uid16.c
··· 176 176 struct group_info *group_info; 177 177 int retval; 178 178 179 - if (!nsown_capable(CAP_SETGID)) 179 + if (!ns_capable(current_user_ns(), CAP_SETGID)) 180 180 return -EPERM; 181 181 if ((unsigned)gidsetsize > NGROUPS_MAX) 182 182 return -EINVAL;
+1 -1
kernel/utsname.c
··· 114 114 struct uts_namespace *ns = new; 115 115 116 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 118 return -EPERM; 119 119 120 120 get_uts_ns(ns);
+1 -1
net/core/net_namespace.c
··· 651 651 struct net *net = ns; 652 652 653 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 655 return -EPERM; 656 656 657 657 put_net(nsproxy->net_ns);
+2 -2
net/core/scm.c
··· 56 56 if ((creds->pid == task_tgid_vnr(current) || 57 57 ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) && 58 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 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 62 return 0; 63 63 } 64 64 return -EPERM;