Skip to content

Commit

Permalink
CRED: Wrap task credential accesses in the core kernel
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: James Morris <[email protected]>
Acked-by: Serge Hallyn <[email protected]>
Cc: Al Viro <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
dhowells authored and James Morris committed Nov 13, 2008
1 parent b103c59 commit 76aac0e
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 52 deletions.
7 changes: 3 additions & 4 deletions kernel/acct.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions kernel/auditsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions kernel/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
Expand Down
8 changes: 5 additions & 3 deletions kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion kernel/futex_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
15 changes: 9 additions & 6 deletions kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 7 additions & 4 deletions kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -5180,8 +5181,9 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
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;
}

Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand Down
15 changes: 9 additions & 6 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(&current->sighand->siglock);
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down
16 changes: 8 additions & 8 deletions kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1641,7 +1641,7 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)

static int test_perm(int mode, int op)
{
if (!current->euid)
if (!current_euid())
mode >>= 6;
else if (in_egroup_p(0))
mode >>= 3;
Expand Down
8 changes: 4 additions & 4 deletions kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion kernel/user_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 5 additions & 2 deletions mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions mm/migrate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 76aac0e

Please sign in to comment.