]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Lock session and group ID setting
authorIngo Molnar <mingo@elte.hu>
Sun, 9 Feb 2003 08:59:53 +0000 (00:59 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 9 Feb 2003 08:59:53 +0000 (00:59 -0800)
 - 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.

fs/jffs/intrep.c
include/linux/sched.h
kernel/exit.c
kernel/kmod.c
kernel/sys.c

index 6cf3d86a5d7938535a1e1ede84df3e902bd894a2..75dfa360cc55d029eaeb6ee2004af44e97210c69 100644 (file)
@@ -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(&current->sighand->siglock);
        siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
index 975dd5dca713c9264cd1d28ffe7ee2ad642c1364..c5ff8e452d4905ce8de673dae87ff9838c7ce194 100644 (file)
@@ -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);
index 98188558e3cf4c7a563283f731da1e4b4a834b44..729e93bff8e48476043abf2d28845ae455b9221f 100644 (file)
@@ -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 */
index 2b85eff87f43b6c096ee2d28dfc2496ce95f65c9..1930367d37362f372081234cbd21ff27bf74919b 100644 (file)
@@ -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();
 
index 10c8db1c887b1117069ddcc72648ea5a35d66d35..9404304eba749cf7e15846654d370d1de2417425 100644 (file)
@@ -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;