Commit c7b96acf authored by Eric W. Biederman's avatar Eric W. Biederman

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: default avatarSerge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent f54fb863
...@@ -2929,8 +2929,8 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) ...@@ -2929,8 +2929,8 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns)
struct path root; struct path root;
if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
!nsown_capable(CAP_SYS_CHROOT) || !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
!nsown_capable(CAP_SYS_ADMIN)) !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (fs->users != 1) if (fs->users != 1)
......
...@@ -443,7 +443,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename) ...@@ -443,7 +443,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
goto dput_and_out; goto dput_and_out;
error = -EPERM; error = -EPERM;
if (!nsown_capable(CAP_SYS_CHROOT)) if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
goto dput_and_out; goto dput_and_out;
error = security_path_chroot(&path); error = security_path_chroot(&path);
if (error) if (error)
......
...@@ -210,7 +210,6 @@ extern bool has_ns_capability_noaudit(struct task_struct *t, ...@@ -210,7 +210,6 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
struct user_namespace *ns, int cap); struct user_namespace *ns, int cap);
extern bool capable(int cap); extern bool capable(int cap);
extern bool ns_capable(struct user_namespace *ns, int cap); extern bool ns_capable(struct user_namespace *ns, int cap);
extern bool nsown_capable(int cap);
extern bool inode_capable(const struct inode *inode, int cap); extern bool inode_capable(const struct inode *inode, int cap);
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
......
...@@ -171,7 +171,7 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new) ...@@ -171,7 +171,7 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new)
{ {
struct ipc_namespace *ns = new; struct ipc_namespace *ns = new;
if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
!nsown_capable(CAP_SYS_ADMIN)) !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
/* Ditch state from the old ipc namespace */ /* Ditch state from the old ipc namespace */
......
...@@ -432,18 +432,6 @@ bool capable(int cap) ...@@ -432,18 +432,6 @@ bool capable(int cap)
} }
EXPORT_SYMBOL(capable); EXPORT_SYMBOL(capable);
/**
* nsown_capable - Check superior capability to one's own user_ns
* @cap: The capability in question
*
* Return true if the current task has the given superior capability
* targeted at its own user namespace.
*/
bool nsown_capable(int cap)
{
return ns_capable(current_user_ns(), cap);
}
/** /**
* inode_capable - Check superior capability over inode * inode_capable - Check superior capability over inode
* @inode: The inode in question * @inode: The inode in question
......
...@@ -233,7 +233,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) ...@@ -233,7 +233,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist)
struct group_info *group_info; struct group_info *group_info;
int retval; int retval;
if (!nsown_capable(CAP_SETGID)) if (!ns_capable(current_user_ns(), CAP_SETGID))
return -EPERM; return -EPERM;
if ((unsigned)gidsetsize > NGROUPS_MAX) if ((unsigned)gidsetsize > NGROUPS_MAX)
return -EINVAL; return -EINVAL;
......
...@@ -329,7 +329,7 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns) ...@@ -329,7 +329,7 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns)
struct pid_namespace *ancestor, *new = ns; struct pid_namespace *ancestor, *new = ns;
if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) || if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) ||
!nsown_capable(CAP_SYS_ADMIN)) !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
/* /*
......
...@@ -337,7 +337,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) ...@@ -337,7 +337,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
if (rgid != (gid_t) -1) { if (rgid != (gid_t) -1) {
if (gid_eq(old->gid, krgid) || if (gid_eq(old->gid, krgid) ||
gid_eq(old->egid, krgid) || gid_eq(old->egid, krgid) ||
nsown_capable(CAP_SETGID)) ns_capable(old->user_ns, CAP_SETGID))
new->gid = krgid; new->gid = krgid;
else else
goto error; goto error;
...@@ -346,7 +346,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) ...@@ -346,7 +346,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
if (gid_eq(old->gid, kegid) || if (gid_eq(old->gid, kegid) ||
gid_eq(old->egid, kegid) || gid_eq(old->egid, kegid) ||
gid_eq(old->sgid, kegid) || gid_eq(old->sgid, kegid) ||
nsown_capable(CAP_SETGID)) ns_capable(old->user_ns, CAP_SETGID))
new->egid = kegid; new->egid = kegid;
else else
goto error; goto error;
...@@ -387,7 +387,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid) ...@@ -387,7 +387,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
old = current_cred(); old = current_cred();
retval = -EPERM; retval = -EPERM;
if (nsown_capable(CAP_SETGID)) if (ns_capable(old->user_ns, CAP_SETGID))
new->gid = new->egid = new->sgid = new->fsgid = kgid; new->gid = new->egid = new->sgid = new->fsgid = kgid;
else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
new->egid = new->fsgid = kgid; new->egid = new->fsgid = kgid;
...@@ -471,7 +471,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) ...@@ -471,7 +471,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
new->uid = kruid; new->uid = kruid;
if (!uid_eq(old->uid, kruid) && if (!uid_eq(old->uid, kruid) &&
!uid_eq(old->euid, kruid) && !uid_eq(old->euid, kruid) &&
!nsown_capable(CAP_SETUID)) !ns_capable(old->user_ns, CAP_SETUID))
goto error; goto error;
} }
...@@ -480,7 +480,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) ...@@ -480,7 +480,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
if (!uid_eq(old->uid, keuid) && if (!uid_eq(old->uid, keuid) &&
!uid_eq(old->euid, keuid) && !uid_eq(old->euid, keuid) &&
!uid_eq(old->suid, keuid) && !uid_eq(old->suid, keuid) &&
!nsown_capable(CAP_SETUID)) !ns_capable(old->user_ns, CAP_SETUID))
goto error; goto error;
} }
...@@ -534,7 +534,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid) ...@@ -534,7 +534,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
old = current_cred(); old = current_cred();
retval = -EPERM; retval = -EPERM;
if (nsown_capable(CAP_SETUID)) { if (ns_capable(old->user_ns, CAP_SETUID)) {
new->suid = new->uid = kuid; new->suid = new->uid = kuid;
if (!uid_eq(kuid, old->uid)) { if (!uid_eq(kuid, old->uid)) {
retval = set_user(new); retval = set_user(new);
...@@ -591,7 +591,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) ...@@ -591,7 +591,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
old = current_cred(); old = current_cred();
retval = -EPERM; retval = -EPERM;
if (!nsown_capable(CAP_SETUID)) { if (!ns_capable(old->user_ns, CAP_SETUID)) {
if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) && if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
!uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid)) !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
goto error; goto error;
...@@ -673,7 +673,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) ...@@ -673,7 +673,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
old = current_cred(); old = current_cred();
retval = -EPERM; retval = -EPERM;
if (!nsown_capable(CAP_SETGID)) { if (!ns_capable(old->user_ns, CAP_SETGID)) {
if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) && if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
!gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid)) !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
goto error; goto error;
...@@ -744,7 +744,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid) ...@@ -744,7 +744,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) || if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) || uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
nsown_capable(CAP_SETUID)) { ns_capable(old->user_ns, CAP_SETUID)) {
if (!uid_eq(kuid, old->fsuid)) { if (!uid_eq(kuid, old->fsuid)) {
new->fsuid = kuid; new->fsuid = kuid;
if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
...@@ -783,7 +783,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid) ...@@ -783,7 +783,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) || if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) || gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
nsown_capable(CAP_SETGID)) { ns_capable(old->user_ns, CAP_SETGID)) {
if (!gid_eq(kgid, old->fsgid)) { if (!gid_eq(kgid, old->fsgid)) {
new->fsgid = kgid; new->fsgid = kgid;
goto change_okay; goto change_okay;
......
...@@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) ...@@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
struct group_info *group_info; struct group_info *group_info;
int retval; int retval;
if (!nsown_capable(CAP_SETGID)) if (!ns_capable(current_user_ns(), CAP_SETGID))
return -EPERM; return -EPERM;
if ((unsigned)gidsetsize > NGROUPS_MAX) if ((unsigned)gidsetsize > NGROUPS_MAX)
return -EINVAL; return -EINVAL;
......
...@@ -114,7 +114,7 @@ static int utsns_install(struct nsproxy *nsproxy, void *new) ...@@ -114,7 +114,7 @@ static int utsns_install(struct nsproxy *nsproxy, void *new)
struct uts_namespace *ns = new; struct uts_namespace *ns = new;
if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
!nsown_capable(CAP_SYS_ADMIN)) !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
get_uts_ns(ns); get_uts_ns(ns);
......
...@@ -651,7 +651,7 @@ static int netns_install(struct nsproxy *nsproxy, void *ns) ...@@ -651,7 +651,7 @@ static int netns_install(struct nsproxy *nsproxy, void *ns)
struct net *net = ns; struct net *net = ns;
if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) || if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
!nsown_capable(CAP_SYS_ADMIN)) !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
put_net(nsproxy->net_ns); put_net(nsproxy->net_ns);
......
...@@ -56,9 +56,9 @@ static __inline__ int scm_check_creds(struct ucred *creds) ...@@ -56,9 +56,9 @@ static __inline__ int scm_check_creds(struct ucred *creds)
if ((creds->pid == task_tgid_vnr(current) || if ((creds->pid == task_tgid_vnr(current) ||
ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) && ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) &&
((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) ||
uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) && uid_eq(uid, cred->suid)) || ns_capable(cred->user_ns, CAP_SETUID)) &&
((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) ||
gid_eq(gid, cred->sgid)) || nsown_capable(CAP_SETGID))) { gid_eq(gid, cred->sgid)) || ns_capable(cred->user_ns, CAP_SETGID))) {
return 0; return 0;
} }
return -EPERM; return -EPERM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment