diff options
| author | Ingo Molnar <mingo@elte.hu> | 2003-02-09 00:59:53 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-09 00:59:53 -0800 |
| commit | e2e6adf5a135aeddf389174473984b7b61582c68 (patch) | |
| tree | 6e66aedefa9469030c885654c4bcb8e1b8f896aa | |
| parent | 8397990bbd169416439f86e567d8fe130250c91f (diff) | |
[PATCH] Lock session and group ID setting
- session-IDs and group-IDs are set outside the tasklist lock. This
causes breakage in the USB code. The correct fix is to do this:
I introduced the bug with the new pidhash.
| -rw-r--r-- | fs/jffs/intrep.c | 3 | ||||
| -rw-r--r-- | include/linux/sched.h | 2 | ||||
| -rw-r--r-- | kernel/exit.c | 26 | ||||
| -rw-r--r-- | kernel/kmod.c | 3 | ||||
| -rw-r--r-- | kernel/sys.c | 11 |
5 files changed, 29 insertions, 16 deletions
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index 6cf3d86a5d79..75dfa360cc55 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c @@ -3344,8 +3344,7 @@ jffs_garbage_collect_thread(void *ptr) lock_kernel(); exit_mm(c->gc_task); - current->session = 1; - current->pgrp = 1; + set_special_pids(1, 1); init_completion(&c->gc_thread_comp); /* barrier */ spin_lock_irq(¤t->sighand->siglock); siginitsetinv (¤t->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT)); diff --git a/include/linux/sched.h b/include/linux/sched.h index 975dd5dca713..c5ff8e452d49 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -503,6 +503,8 @@ extern struct task_struct init_task; extern struct mm_struct init_mm; extern struct task_struct *find_task_by_pid(int pid); +extern void set_special_pids(pid_t session, pid_t pgrp); +extern void __set_special_pids(pid_t session, pid_t pgrp); /* per-UID process charging. */ extern struct user_struct * alloc_uid(uid_t); diff --git a/kernel/exit.c b/kernel/exit.c index 98188558e3cf..729e93bff8e4 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -254,6 +254,29 @@ void reparent_to_init(void) write_unlock_irq(&tasklist_lock); } +void __set_special_pids(pid_t session, pid_t pgrp) +{ + struct task_struct *curr = current; + + if (curr->session != session) { + detach_pid(curr, PIDTYPE_SID); + curr->session = session; + attach_pid(curr, PIDTYPE_SID, session); + } + if (curr->pgrp != pgrp) { + detach_pid(curr, PIDTYPE_PGID); + curr->pgrp = pgrp; + attach_pid(curr, PIDTYPE_PGID, pgrp); + } +} + +void set_special_pids(pid_t session, pid_t pgrp) +{ + write_lock_irq(&tasklist_lock); + __set_special_pids(session, pgrp); + write_unlock_irq(&tasklist_lock); +} + /* * Put all the gunge required to become a kernel thread without * attached user resources in one place where it belongs. @@ -271,8 +294,7 @@ void daemonize(void) */ exit_mm(current); - current->session = 1; - current->pgrp = 1; + set_special_pids(1, 1); current->tty = NULL; /* Become as one with the init task */ diff --git a/kernel/kmod.c b/kernel/kmod.c index 2b85eff87f43..1930367d3736 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -100,8 +100,7 @@ int exec_usermodehelper(char *program_path, char *argv[], char *envp[]) int i; struct task_struct *curtask = current; - curtask->session = 1; - curtask->pgrp = 1; + set_special_pids(1, 1); use_init_fs_context(); diff --git a/kernel/sys.c b/kernel/sys.c index 10c8db1c887b..9404304eba74 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1021,16 +1021,7 @@ asmlinkage long sys_setsid(void) goto out; current->leader = 1; - if (current->session != current->pid) { - detach_pid(current, PIDTYPE_SID); - current->session = current->pid; - attach_pid(current, PIDTYPE_SID, current->pid); - } - if (current->pgrp != current->pid) { - detach_pid(current, PIDTYPE_PGID); - current->pgrp = current->pid; - attach_pid(current, PIDTYPE_PGID, current->pid); - } + __set_special_pids(current->pid, current->pid); current->tty = NULL; current->tty_old_pgrp = 0; err = current->pgrp; |
