Commit 3b149cc7 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] remove lock_kernel() from exec of setuid apps

Patch from Manfred Spraul <manfred@colorfullife.com>

exec of setuid apps and ptrace must be synchronized, to ensure that a normal
user cannot ptrace a setuid app across exec.  ptrace_attach acquires the
task_lock around the uid checks, compute_creds acquires the BLK.  The patch
converts compute_creds to the task_lock.  Additionally, it removes the
do_unlock variable: the task_lock is not heaviliy used, there is no need to
avoid the spinlock by adding branches.

The patch is a cleanup patch, not a fix for a security problem: AFAICS the
sys_ptrace in every arch acquires the BKL before calling ptrace_attach.
parent db54e742
...@@ -873,12 +873,10 @@ int prepare_binprm(struct linux_binprm *bprm) ...@@ -873,12 +873,10 @@ int prepare_binprm(struct linux_binprm *bprm)
void compute_creds(struct linux_binprm *bprm) void compute_creds(struct linux_binprm *bprm)
{ {
int do_unlock = 0; task_lock(current);
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) { if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
current->mm->dumpable = 0; current->mm->dumpable = 0;
lock_kernel();
if (must_not_trace_exec(current) if (must_not_trace_exec(current)
|| atomic_read(&current->fs->count) > 1 || atomic_read(&current->fs->count) > 1
|| atomic_read(&current->files->count) > 1 || atomic_read(&current->files->count) > 1
...@@ -888,14 +886,12 @@ void compute_creds(struct linux_binprm *bprm) ...@@ -888,14 +886,12 @@ void compute_creds(struct linux_binprm *bprm)
bprm->e_gid = current->gid; bprm->e_gid = current->gid;
} }
} }
do_unlock = 1;
} }
current->suid = current->euid = current->fsuid = bprm->e_uid; current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid; current->sgid = current->egid = current->fsgid = bprm->e_gid;
if(do_unlock) task_unlock(current);
unlock_kernel();
security_bprm_compute_creds(bprm); security_bprm_compute_creds(bprm);
} }
......
...@@ -120,17 +120,16 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm) ...@@ -120,17 +120,16 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm)
{ {
/* Derived from fs/exec.c:compute_creds. */ /* Derived from fs/exec.c:compute_creds. */
kernel_cap_t new_permitted, working; kernel_cap_t new_permitted, working;
int do_unlock = 0;
new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
working = cap_intersect (bprm->cap_inheritable, working = cap_intersect (bprm->cap_inheritable,
current->cap_inheritable); current->cap_inheritable);
new_permitted = cap_combine (new_permitted, working); new_permitted = cap_combine (new_permitted, working);
task_lock(current);
if (!cap_issubset (new_permitted, current->cap_permitted)) { if (!cap_issubset (new_permitted, current->cap_permitted)) {
current->mm->dumpable = 0; current->mm->dumpable = 0;
lock_kernel ();
if (must_not_trace_exec (current) if (must_not_trace_exec (current)
|| atomic_read (&current->fs->count) > 1 || atomic_read (&current->fs->count) > 1
|| atomic_read (&current->files->count) > 1 || atomic_read (&current->files->count) > 1
...@@ -141,7 +140,6 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm) ...@@ -141,7 +140,6 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm)
cap_permitted); cap_permitted);
} }
} }
do_unlock = 1;
} }
/* For init, we want to retain the capabilities set /* For init, we want to retain the capabilities set
...@@ -154,9 +152,7 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm) ...@@ -154,9 +152,7 @@ void cap_bprm_compute_creds (struct linux_binprm *bprm)
} }
/* AUD: Audit candidate if current->cap_effective is set */ /* AUD: Audit candidate if current->cap_effective is set */
task_unlock(current);
if (do_unlock)
unlock_kernel ();
current->keep_capabilities = 0; current->keep_capabilities = 0;
} }
......
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