mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
CRED: Wrap task credential accesses in the core kernel
Wrap access to task credentials so that they can be separated more easily from the task_struct during the introduction of COW creds. Change most current->(|e|s|fs)[ug]id to current_(|e|s|fs)[ug]id(). Change some task->e?[ug]id to task_e?[ug]id(). In some places it makes more sense to use RCU directly rather than a convenient wrapper; these will be addressed by later patches. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: linux-audit@redhat.com Cc: containers@lists.linux-foundation.org Cc: linux-mm@kvack.org Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
b103c59883
commit
76aac0e9a1
@ -530,15 +530,14 @@ static void do_acct_process(struct bsd_acct_struct *acct,
|
||||
do_div(elapsed, AHZ);
|
||||
ac.ac_btime = get_seconds() - elapsed;
|
||||
/* we really need to bite the bullet and change layout */
|
||||
ac.ac_uid = current->uid;
|
||||
ac.ac_gid = current->gid;
|
||||
current_uid_gid(&ac.ac_uid, &ac.ac_gid);
|
||||
#if ACCT_VERSION==2
|
||||
ac.ac_ahz = AHZ;
|
||||
#endif
|
||||
#if ACCT_VERSION==1 || ACCT_VERSION==2
|
||||
/* backward-compatible 16 bit fields */
|
||||
ac.ac_uid16 = current->uid;
|
||||
ac.ac_gid16 = current->gid;
|
||||
ac.ac_uid16 = ac.ac_uid;
|
||||
ac.ac_gid16 = ac.ac_gid;
|
||||
#endif
|
||||
#if ACCT_VERSION==3
|
||||
ac.ac_pid = task_tgid_nr_ns(current, ns);
|
||||
|
@ -2628,7 +2628,8 @@ void audit_core_dumps(long signr)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
u32 sid;
|
||||
uid_t auid = audit_get_loginuid(current);
|
||||
uid_t auid = audit_get_loginuid(current), uid;
|
||||
gid_t gid;
|
||||
unsigned int sessionid = audit_get_sessionid(current);
|
||||
|
||||
if (!audit_enabled)
|
||||
@ -2638,8 +2639,9 @@ void audit_core_dumps(long signr)
|
||||
return;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
|
||||
current_uid_gid(&uid, &gid);
|
||||
audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
|
||||
auid, current->uid, current->gid, sessionid);
|
||||
auid, uid, gid, sessionid);
|
||||
security_task_getsecid(current, &sid);
|
||||
if (sid) {
|
||||
char *ctx = NULL;
|
||||
|
@ -571,8 +571,8 @@ static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
|
||||
|
||||
if (inode) {
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_blocks = 0;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
|
||||
@ -1279,6 +1279,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
|
||||
static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
uid_t euid;
|
||||
int ret;
|
||||
|
||||
if (pid) {
|
||||
@ -1291,8 +1292,8 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
|
||||
get_task_struct(tsk);
|
||||
rcu_read_unlock();
|
||||
|
||||
if ((current->euid) && (current->euid != tsk->uid)
|
||||
&& (current->euid != tsk->suid)) {
|
||||
euid = current_euid();
|
||||
if (euid && euid != tsk->uid && euid != tsk->suid) {
|
||||
put_task_struct(tsk);
|
||||
return -EACCES;
|
||||
}
|
||||
|
@ -439,10 +439,11 @@ static void free_pi_state(struct futex_pi_state *pi_state)
|
||||
static struct task_struct * futex_find_get_task(pid_t pid)
|
||||
{
|
||||
struct task_struct *p;
|
||||
uid_t euid = current_euid();
|
||||
|
||||
rcu_read_lock();
|
||||
p = find_task_by_vpid(pid);
|
||||
if (!p || ((current->euid != p->euid) && (current->euid != p->uid)))
|
||||
if (!p || (euid != p->euid && euid != p->uid))
|
||||
p = ERR_PTR(-ESRCH);
|
||||
else
|
||||
get_task_struct(p);
|
||||
@ -1829,6 +1830,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
|
||||
{
|
||||
struct robust_list_head __user *head;
|
||||
unsigned long ret;
|
||||
uid_t euid = current_euid();
|
||||
|
||||
if (!futex_cmpxchg_enabled)
|
||||
return -ENOSYS;
|
||||
@ -1844,8 +1846,8 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
|
||||
if (!p)
|
||||
goto err_unlock;
|
||||
ret = -EPERM;
|
||||
if ((current->euid != p->euid) && (current->euid != p->uid) &&
|
||||
!capable(CAP_SYS_PTRACE))
|
||||
if (euid != p->euid && euid != p->uid &&
|
||||
!capable(CAP_SYS_PTRACE))
|
||||
goto err_unlock;
|
||||
head = p->robust_list;
|
||||
rcu_read_unlock();
|
||||
|
@ -135,6 +135,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
|
||||
{
|
||||
struct compat_robust_list_head __user *head;
|
||||
unsigned long ret;
|
||||
uid_t euid = current_euid();
|
||||
|
||||
if (!futex_cmpxchg_enabled)
|
||||
return -ENOSYS;
|
||||
@ -150,7 +151,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
|
||||
if (!p)
|
||||
goto err_unlock;
|
||||
ret = -EPERM;
|
||||
if ((current->euid != p->euid) && (current->euid != p->uid) &&
|
||||
if (euid != p->euid && euid != p->uid &&
|
||||
!capable(CAP_SYS_PTRACE))
|
||||
goto err_unlock;
|
||||
head = p->compat_robust_list;
|
||||
|
@ -123,16 +123,19 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
|
||||
* because setting up the necessary parent/child relationship
|
||||
* or halting the specified task is impossible.
|
||||
*/
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int dumpable = 0;
|
||||
/* Don't let security modules deny introspection */
|
||||
if (task == current)
|
||||
return 0;
|
||||
if (((current->uid != task->euid) ||
|
||||
(current->uid != task->suid) ||
|
||||
(current->uid != task->uid) ||
|
||||
(current->gid != task->egid) ||
|
||||
(current->gid != task->sgid) ||
|
||||
(current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
|
||||
current_uid_gid(&uid, &gid);
|
||||
if ((uid != task->euid ||
|
||||
uid != task->suid ||
|
||||
uid != task->uid ||
|
||||
gid != task->egid ||
|
||||
gid != task->sgid ||
|
||||
gid != task->gid) && !capable(CAP_SYS_PTRACE))
|
||||
return -EPERM;
|
||||
smp_rmb();
|
||||
if (task->mm)
|
||||
|
@ -5128,6 +5128,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
|
||||
unsigned long flags;
|
||||
const struct sched_class *prev_class = p->sched_class;
|
||||
struct rq *rq;
|
||||
uid_t euid;
|
||||
|
||||
/* may grab non-irq protected spin_locks */
|
||||
BUG_ON(in_interrupt());
|
||||
@ -5180,8 +5181,9 @@ recheck:
|
||||
return -EPERM;
|
||||
|
||||
/* can't change other user's priorities */
|
||||
if ((current->euid != p->euid) &&
|
||||
(current->euid != p->uid))
|
||||
euid = current_euid();
|
||||
if (euid != p->euid &&
|
||||
euid != p->uid)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
@ -5392,6 +5394,7 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
|
||||
cpumask_t cpus_allowed;
|
||||
cpumask_t new_mask = *in_mask;
|
||||
struct task_struct *p;
|
||||
uid_t euid;
|
||||
int retval;
|
||||
|
||||
get_online_cpus();
|
||||
@ -5412,9 +5415,9 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
|
||||
get_task_struct(p);
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
euid = current_euid();
|
||||
retval = -EPERM;
|
||||
if ((current->euid != p->euid) && (current->euid != p->uid) &&
|
||||
!capable(CAP_SYS_NICE))
|
||||
if (euid != p->euid && euid != p->uid && !capable(CAP_SYS_NICE))
|
||||
goto out_unlock;
|
||||
|
||||
retval = security_task_setscheduler(p, 0, NULL);
|
||||
|
@ -567,6 +567,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
|
||||
struct task_struct *t)
|
||||
{
|
||||
struct pid *sid;
|
||||
uid_t uid, euid;
|
||||
int error;
|
||||
|
||||
if (!valid_signal(sig))
|
||||
@ -579,8 +580,10 @@ static int check_kill_permission(int sig, struct siginfo *info,
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if ((current->euid ^ t->suid) && (current->euid ^ t->uid) &&
|
||||
(current->uid ^ t->suid) && (current->uid ^ t->uid) &&
|
||||
uid = current_uid();
|
||||
euid = current_euid();
|
||||
if ((euid ^ t->suid) && (euid ^ t->uid) &&
|
||||
(uid ^ t->suid) && (uid ^ t->uid) &&
|
||||
!capable(CAP_KILL)) {
|
||||
switch (sig) {
|
||||
case SIGCONT:
|
||||
@ -844,7 +847,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
q->info.si_errno = 0;
|
||||
q->info.si_code = SI_USER;
|
||||
q->info.si_pid = task_pid_vnr(current);
|
||||
q->info.si_uid = current->uid;
|
||||
q->info.si_uid = current_uid();
|
||||
break;
|
||||
case (unsigned long) SEND_SIG_PRIV:
|
||||
q->info.si_signo = sig;
|
||||
@ -1598,7 +1601,7 @@ void ptrace_notify(int exit_code)
|
||||
info.si_signo = SIGTRAP;
|
||||
info.si_code = exit_code;
|
||||
info.si_pid = task_pid_vnr(current);
|
||||
info.si_uid = current->uid;
|
||||
info.si_uid = current_uid();
|
||||
|
||||
/* Let the debugger run. */
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
@ -2211,7 +2214,7 @@ sys_kill(pid_t pid, int sig)
|
||||
info.si_errno = 0;
|
||||
info.si_code = SI_USER;
|
||||
info.si_pid = task_tgid_vnr(current);
|
||||
info.si_uid = current->uid;
|
||||
info.si_uid = current_uid();
|
||||
|
||||
return kill_something_info(sig, &info, pid);
|
||||
}
|
||||
@ -2228,7 +2231,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
|
||||
info.si_errno = 0;
|
||||
info.si_code = SI_TKILL;
|
||||
info.si_pid = task_tgid_vnr(current);
|
||||
info.si_uid = current->uid;
|
||||
info.si_uid = current_uid();
|
||||
|
||||
rcu_read_lock();
|
||||
p = find_task_by_vpid(pid);
|
||||
|
16
kernel/sys.c
16
kernel/sys.c
@ -114,10 +114,10 @@ void (*pm_power_off_prepare)(void);
|
||||
|
||||
static int set_one_prio(struct task_struct *p, int niceval, int error)
|
||||
{
|
||||
uid_t euid = current_euid();
|
||||
int no_nice;
|
||||
|
||||
if (p->uid != current->euid &&
|
||||
p->euid != current->euid && !capable(CAP_SYS_NICE)) {
|
||||
if (p->uid != euid && p->euid != euid && !capable(CAP_SYS_NICE)) {
|
||||
error = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
@ -176,16 +176,16 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
|
||||
case PRIO_USER:
|
||||
user = current->user;
|
||||
if (!who)
|
||||
who = current->uid;
|
||||
who = current_uid();
|
||||
else
|
||||
if ((who != current->uid) && !(user = find_user(who)))
|
||||
if (who != current_uid() && !(user = find_user(who)))
|
||||
goto out_unlock; /* No processes for this user */
|
||||
|
||||
do_each_thread(g, p)
|
||||
if (p->uid == who)
|
||||
error = set_one_prio(p, niceval, error);
|
||||
while_each_thread(g, p);
|
||||
if (who != current->uid)
|
||||
if (who != current_uid())
|
||||
free_uid(user); /* For find_user() */
|
||||
break;
|
||||
}
|
||||
@ -238,9 +238,9 @@ asmlinkage long sys_getpriority(int which, int who)
|
||||
case PRIO_USER:
|
||||
user = current->user;
|
||||
if (!who)
|
||||
who = current->uid;
|
||||
who = current_uid();
|
||||
else
|
||||
if ((who != current->uid) && !(user = find_user(who)))
|
||||
if (who != current_uid() && !(user = find_user(who)))
|
||||
goto out_unlock; /* No processes for this user */
|
||||
|
||||
do_each_thread(g, p)
|
||||
@ -250,7 +250,7 @@ asmlinkage long sys_getpriority(int which, int who)
|
||||
retval = niceval;
|
||||
}
|
||||
while_each_thread(g, p);
|
||||
if (who != current->uid)
|
||||
if (who != current_uid())
|
||||
free_uid(user); /* for find_user() */
|
||||
break;
|
||||
}
|
||||
|
@ -1641,7 +1641,7 @@ out:
|
||||
|
||||
static int test_perm(int mode, int op)
|
||||
{
|
||||
if (!current->euid)
|
||||
if (!current_euid())
|
||||
mode >>= 6;
|
||||
else if (in_egroup_p(0))
|
||||
mode >>= 3;
|
||||
|
@ -1123,25 +1123,25 @@ asmlinkage long sys_getppid(void)
|
||||
asmlinkage long sys_getuid(void)
|
||||
{
|
||||
/* Only we change this so SMP safe */
|
||||
return current->uid;
|
||||
return current_uid();
|
||||
}
|
||||
|
||||
asmlinkage long sys_geteuid(void)
|
||||
{
|
||||
/* Only we change this so SMP safe */
|
||||
return current->euid;
|
||||
return current_euid();
|
||||
}
|
||||
|
||||
asmlinkage long sys_getgid(void)
|
||||
{
|
||||
/* Only we change this so SMP safe */
|
||||
return current->gid;
|
||||
return current_gid();
|
||||
}
|
||||
|
||||
asmlinkage long sys_getegid(void)
|
||||
{
|
||||
/* Only we change this so SMP safe */
|
||||
return current->egid;
|
||||
return current_egid();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@ static struct user_namespace *clone_user_ns(struct user_namespace *old_ns)
|
||||
}
|
||||
|
||||
/* Reset current->user with a new one */
|
||||
new_user = alloc_uid(ns, current->uid);
|
||||
new_user = alloc_uid(ns, current_uid());
|
||||
if (!new_user) {
|
||||
free_uid(ns->root_user);
|
||||
kfree(ns);
|
||||
|
@ -1115,6 +1115,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
|
||||
nodemask_t old;
|
||||
nodemask_t new;
|
||||
nodemask_t task_nodes;
|
||||
uid_t uid, euid;
|
||||
int err;
|
||||
|
||||
err = get_nodes(&old, old_nodes, maxnode);
|
||||
@ -1144,8 +1145,10 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
|
||||
* capabilities, superuser privileges or the same
|
||||
* userid as the target process.
|
||||
*/
|
||||
if ((current->euid != task->suid) && (current->euid != task->uid) &&
|
||||
(current->uid != task->suid) && (current->uid != task->uid) &&
|
||||
uid = current_uid();
|
||||
euid = current_euid();
|
||||
if (euid != task->suid && euid != task->uid &&
|
||||
uid != task->suid && uid != task->uid &&
|
||||
!capable(CAP_SYS_NICE)) {
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
|
@ -1048,6 +1048,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
|
||||
struct task_struct *task;
|
||||
struct mm_struct *mm;
|
||||
int err;
|
||||
uid_t uid, euid;
|
||||
|
||||
/* Check flags */
|
||||
if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
|
||||
@ -1075,8 +1076,10 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
|
||||
* capabilities, superuser privileges or the same
|
||||
* userid as the target process.
|
||||
*/
|
||||
if ((current->euid != task->suid) && (current->euid != task->uid) &&
|
||||
(current->uid != task->suid) && (current->uid != task->uid) &&
|
||||
uid = current_uid();
|
||||
euid = current_euid();
|
||||
if (euid != task->suid && euid != task->uid &&
|
||||
uid != task->suid && uid != task->uid &&
|
||||
!capable(CAP_SYS_NICE)) {
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
|
@ -1513,8 +1513,8 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
|
||||
inode = new_inode(sb);
|
||||
if (inode) {
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_blocks = 0;
|
||||
inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
@ -2278,8 +2278,8 @@ static int shmem_fill_super(struct super_block *sb,
|
||||
sbinfo->max_blocks = 0;
|
||||
sbinfo->max_inodes = 0;
|
||||
sbinfo->mode = S_IRWXUGO | S_ISVTX;
|
||||
sbinfo->uid = current->fsuid;
|
||||
sbinfo->gid = current->fsgid;
|
||||
sbinfo->uid = current_fsuid();
|
||||
sbinfo->gid = current_fsgid();
|
||||
sbinfo->mpol = NULL;
|
||||
sb->s_fs_info = sbinfo;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user