summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-02-10 07:37:12 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-02-10 07:37:12 -0800
commitb789ebfca657a1fc77f6bd4dd648c0d5e96057c8 (patch)
tree96074583f732c733a6a62eabe48ca7f35203be98 /kernel
parent3322be329b2b75c784e0614aee71adc0dff2afdc (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.c2
-rw-r--r--kernel/kmod.c10
-rw-r--r--kernel/sys.c13
-rw-r--r--kernel/user.c17
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)
{