Commit 5b5a877d authored by Ingo Molnar's avatar Ingo Molnar

[PATCH] sigfix-2.5.39-D0, BK-curr

This fixes a procfs crash noticed by Anton Blanchard.

The procfs code can have a reference even to an already exited task, so
it needs to follow special rules accessing p->sig.  The atomic-signals
patch made this bug happen at a much higher frequency, but procfs i
believe was buggy ever since, it potentially used the freed signal
structure - which just did not result in a crash like it does today.

The proper fix is to take the tasklist read-lock in
collect_sigign_sigcatch(), this excludes __exit_sighand() freeing the
signal structure prematurely.
parent fe9b9e34
...@@ -228,8 +228,9 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, ...@@ -228,8 +228,9 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
sigemptyset(ign); sigemptyset(ign);
sigemptyset(catch); sigemptyset(catch);
spin_lock_irq(&p->sig->siglock); read_lock(&tasklist_lock);
if (p->sig) { if (p->sig) {
spin_lock_irq(&p->sig->siglock);
k = p->sig->action; k = p->sig->action;
for (i = 1; i <= _NSIG; ++i, ++k) { for (i = 1; i <= _NSIG; ++i, ++k) {
if (k->sa.sa_handler == SIG_IGN) if (k->sa.sa_handler == SIG_IGN)
...@@ -237,8 +238,9 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, ...@@ -237,8 +238,9 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
else if (k->sa.sa_handler != SIG_DFL) else if (k->sa.sa_handler != SIG_DFL)
sigaddset(catch, i); sigaddset(catch, i);
} }
}
spin_unlock_irq(&p->sig->siglock); spin_unlock_irq(&p->sig->siglock);
}
read_unlock(&tasklist_lock);
} }
static inline char * task_sig(struct task_struct *p, char *buffer) static inline char * task_sig(struct task_struct *p, char *buffer)
......
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