diff options
| author | Andrew Morton <akpm@digeo.com> | 2003-02-10 07:37:12 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-10 07:37:12 -0800 |
| commit | b789ebfca657a1fc77f6bd4dd648c0d5e96057c8 (patch) | |
| tree | 96074583f732c733a6a62eabe48ca7f35203be98 /kernel | |
| parent | 3322be329b2b75c784e0614aee71adc0dff2afdc (diff) | |
[PATCH] fix current->user->processes leak
Patch from: Eric Lammerts <eric@lammerts.org>
Every time you do a loop mount, a kernel thread is started (those
processes are called "loop0", "loop1", etc.). The problem is that when
it starts, it's counted as one of your processes. Then, it's
changed to be a root-owned process without correcting that count.
Patch below fixes the problem. It moves the bookkeeping of changing
current->user to a new function switch_uid() (which is now also used
by exec_usermodehelper() in kmod.c). The patch is tested.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/exit.c | 2 | ||||
| -rw-r--r-- | kernel/kmod.c | 10 | ||||
| -rw-r--r-- | kernel/sys.c | 13 | ||||
| -rw-r--r-- | kernel/user.c | 17 |
4 files changed, 21 insertions, 21 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 729e93bff8e4..de34ed9091f5 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -249,7 +249,7 @@ void reparent_to_init(void) /* signals? */ security_task_reparent_to_init(current); memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim))); - current->user = INIT_USER; + switch_uid(INIT_USER); write_unlock_irq(&tasklist_lock); } diff --git a/kernel/kmod.c b/kernel/kmod.c index 1930367d3736..257634f94652 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -121,15 +121,7 @@ int exec_usermodehelper(char *program_path, char *argv[], char *envp[]) if (curtask->files->fd[i]) close(i); } - /* Drop the "current user" thing */ - { - struct user_struct *user = curtask->user; - curtask->user = INIT_USER; - atomic_inc(&INIT_USER->__count); - atomic_inc(&INIT_USER->processes); - atomic_dec(&user->processes); - free_uid(user); - } + switch_uid(INIT_USER); /* Give kmod all effective privileges.. */ curtask->euid = curtask->fsuid = 0; diff --git a/kernel/sys.c b/kernel/sys.c index 9404304eba74..dffb67035c78 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -561,19 +561,12 @@ asmlinkage long sys_setgid(gid_t gid) static int set_user(uid_t new_ruid, int dumpclear) { - struct user_struct *new_user, *old_user; + struct user_struct *new_user; - /* What if a process setreuid()'s and this brings the - * new uid over his NPROC rlimit? We can check this now - * cheaply with the new uid cache, so if it matters - * we should be checking for it. -DaveM - */ new_user = alloc_uid(new_ruid); if (!new_user) return -EAGAIN; - old_user = current->user; - atomic_dec(&old_user->processes); - atomic_inc(&new_user->processes); + switch_uid(new_user); if(dumpclear) { @@ -581,8 +574,6 @@ static int set_user(uid_t new_ruid, int dumpclear) wmb(); } current->uid = new_ruid; - current->user = new_user; - free_uid(old_user); return 0; } diff --git a/kernel/user.c b/kernel/user.c index 0704b2aad9c5..592680d8cc68 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -116,6 +116,23 @@ struct user_struct * alloc_uid(uid_t uid) return up; } +void switch_uid(struct user_struct *new_user) +{ + struct user_struct *old_user; + + /* What if a process setreuid()'s and this brings the + * new uid over his NPROC rlimit? We can check this now + * cheaply with the new uid cache, so if it matters + * we should be checking for it. -DaveM + */ + old_user = current->user; + atomic_inc(&new_user->__count); + atomic_inc(&new_user->processes); + atomic_dec(&old_user->processes); + current->user = new_user; + free_uid(old_user); +} + static int __init uid_cache_init(void) { |
