mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
f54fb863c6
commit
c7b96acf14
|
@ -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)
|
||||||
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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
20
kernel/sys.c
20
kernel/sys.c
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue