From: Greg Kroah-Hartman Date: Thu, 11 Feb 2010 23:54:04 +0000 (-0800) Subject: start .32 queue X-Git-Tag: v2.6.32.9~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=175a36128231a03785638c54a9dd96d8a1681987;p=thirdparty%2Fkernel%2Fstable-queue.git start .32 queue --- diff --git a/queue-2.6.32/fix-potential-crash-with-sys_move_pages.patch b/queue-2.6.32/fix-potential-crash-with-sys_move_pages.patch new file mode 100644 index 00000000000..6ab70111f84 --- /dev/null +++ b/queue-2.6.32/fix-potential-crash-with-sys_move_pages.patch @@ -0,0 +1,36 @@ +From 6f5a55f1a6c5abee15a0e878e5c74d9f1569b8b0 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 5 Feb 2010 16:16:50 -0800 +Subject: Fix potential crash with sys_move_pages + +From: Linus Torvalds + +commit 6f5a55f1a6c5abee15a0e878e5c74d9f1569b8b0 upstream. + +We incorrectly depended on the 'node_state/node_isset()' functions +testing the node range, rather than checking it explicitly. That's not +reliable, even if it might often happen to work. So do the proper +explicit test. + +Reported-by: Marcus Meissner +Acked-and-tested-by: Brice Goglin +Acked-by: Hugh Dickins +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/migrate.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -953,6 +953,9 @@ static int do_pages_move(struct mm_struc + goto out_pm; + + err = -ENODEV; ++ if (node < 0 || node >= MAX_NUMNODES) ++ goto out_pm; ++ + if (!node_state(node, N_HIGH_MEMORY)) + goto out_pm; + diff --git a/queue-2.6.32/fix-race-in-tty_fasync-properly.patch b/queue-2.6.32/fix-race-in-tty_fasync-properly.patch new file mode 100644 index 00000000000..9c917fc586c --- /dev/null +++ b/queue-2.6.32/fix-race-in-tty_fasync-properly.patch @@ -0,0 +1,83 @@ +From 80e1e823989ec44d8e35bdfddadbddcffec90424 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Sun, 7 Feb 2010 10:11:23 -0800 +Subject: Fix race in tty_fasync() properly + +From: Linus Torvalds + +commit 80e1e823989ec44d8e35bdfddadbddcffec90424 upstream. + +This reverts commit 703625118069 ("tty: fix race in tty_fasync") and +commit b04da8bfdfbb ("fnctl: f_modown should call write_lock_irqsave/ +restore") that tried to fix up some of the fallout but was incomplete. + +It turns out that we really cannot hold 'tty->ctrl_lock' over calling +__f_setown, because not only did that cause problems with interrupt +disables (which the second commit fixed), it also causes a potential +ABBA deadlock due to lock ordering. + +Thanks to Tetsuo Handa for following up on the issue, and running +lockdep to show the problem. It goes roughly like this: + + - f_getown gets filp->f_owner.lock for reading without interrupts + disabled, so an interrupt that happens while that lock is held can + cause a lockdep chain from f_owner.lock -> sighand->siglock. + + - at the same time, the tty->ctrl_lock -> f_owner.lock chain that + commit 703625118069 introduced, together with the pre-existing + sighand->siglock -> tty->ctrl_lock chain means that we have a lock + dependency the other way too. + +So instead of extending tty->ctrl_lock over the whole __f_setown() call, +we now just take a reference to the 'pid' structure while holding the +lock, and then release it after having done the __f_setown. That still +guarantees that 'struct pid' won't go away from under us, which is all +we really ever needed. + +Reported-and-tested-by: Tetsuo Handa +Acked-by: Greg Kroah-Hartman +Acked-by: Américo Wang +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tty_io.c | 4 +++- + fs/fcntl.c | 6 ++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/char/tty_io.c ++++ b/drivers/char/tty_io.c +@@ -1930,8 +1930,10 @@ static int tty_fasync(int fd, struct fil + pid = task_pid(current); + type = PIDTYPE_PID; + } +- retval = __f_setown(filp, pid, type, 0); ++ get_pid(pid); + spin_unlock_irqrestore(&tty->ctrl_lock, flags); ++ retval = __f_setown(filp, pid, type, 0); ++ put_pid(pid); + if (retval) + goto out; + } else { +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -199,9 +199,7 @@ static int setfl(int fd, struct file * f + static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, + int force) + { +- unsigned long flags; +- +- write_lock_irqsave(&filp->f_owner.lock, flags); ++ write_lock_irq(&filp->f_owner.lock); + if (force || !filp->f_owner.pid) { + put_pid(filp->f_owner.pid); + filp->f_owner.pid = get_pid(pid); +@@ -213,7 +211,7 @@ static void f_modown(struct file *filp, + filp->f_owner.euid = cred->euid; + } + } +- write_unlock_irqrestore(&filp->f_owner.lock, flags); ++ write_unlock_irq(&filp->f_owner.lock); + } + + int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, diff --git a/queue-2.6.32/futex-handle-futex-value-corruption-gracefully.patch b/queue-2.6.32/futex-handle-futex-value-corruption-gracefully.patch new file mode 100644 index 00000000000..dbb57c3d676 --- /dev/null +++ b/queue-2.6.32/futex-handle-futex-value-corruption-gracefully.patch @@ -0,0 +1,63 @@ +From 59647b6ac3050dd964bc556fe6ef22f4db5b935c Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 3 Feb 2010 09:33:05 +0100 +Subject: futex: Handle futex value corruption gracefully + +From: Thomas Gleixner + +commit 59647b6ac3050dd964bc556fe6ef22f4db5b935c upstream. + +The WARN_ON in lookup_pi_state which complains about a mismatch +between pi_state->owner->pid and the pid which we retrieved from the +user space futex is completely bogus. + +The code just emits the warning and then continues despite the fact +that it detected an inconsistent state of the futex. A conveniant way +for user space to spam the syslog. + +Replace the WARN_ON by a consistency check. If the values do not match +return -EINVAL and let user space deal with the mess it created. + +This also fixes the missing task_pid_vnr() when we compare the +pi_state->owner pid with the futex value. + +Reported-by: Jermome Marchand +Signed-off-by: Thomas Gleixner +Acked-by: Darren Hart +Acked-by: Peter Zijlstra +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -530,8 +530,25 @@ lookup_pi_state(u32 uval, struct futex_h + return -EINVAL; + + WARN_ON(!atomic_read(&pi_state->refcount)); +- WARN_ON(pid && pi_state->owner && +- pi_state->owner->pid != pid); ++ ++ /* ++ * When pi_state->owner is NULL then the owner died ++ * and another waiter is on the fly. pi_state->owner ++ * is fixed up by the task which acquires ++ * pi_state->rt_mutex. ++ * ++ * We do not check for pid == 0 which can happen when ++ * the owner died and robust_list_exit() cleared the ++ * TID. ++ */ ++ if (pid && pi_state->owner) { ++ /* ++ * Bail out if user space manipulated the ++ * futex value. ++ */ ++ if (pid != task_pid_vnr(pi_state->owner)) ++ return -EINVAL; ++ } + + atomic_inc(&pi_state->refcount); + *ps = pi_state; diff --git a/queue-2.6.32/futex-handle-user-space-corruption-gracefully.patch b/queue-2.6.32/futex-handle-user-space-corruption-gracefully.patch new file mode 100644 index 00000000000..9d4216f9414 --- /dev/null +++ b/queue-2.6.32/futex-handle-user-space-corruption-gracefully.patch @@ -0,0 +1,49 @@ +From 51246bfd189064079c54421507236fd2723b18f3 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Tue, 2 Feb 2010 11:40:27 +0100 +Subject: futex: Handle user space corruption gracefully + +From: Thomas Gleixner + +commit 51246bfd189064079c54421507236fd2723b18f3 upstream. + +If the owner of a PI futex dies we fix up the pi_state and set +pi_state->owner to NULL. When a malicious or just sloppy programmed +user space application sets the futex value to 0 e.g. by calling +pthread_mutex_init(), then the futex can be acquired again. A new +waiter manages to enqueue itself on the pi_state w/o damage, but on +unlock the kernel dereferences pi_state->owner and oopses. + +Prevent this by checking pi_state->owner in the unlock path. If +pi_state->owner is not current we know that user space manipulated the +futex value. Ignore the mess and return -EINVAL. + +This catches the above case and also the case where a task hijacks the +futex by setting the tid value and then tries to unlock it. + +Reported-by: Jermome Marchand +Signed-off-by: Thomas Gleixner +Acked-by: Darren Hart +Acked-by: Peter Zijlstra +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -758,6 +758,13 @@ static int wake_futex_pi(u32 __user *uad + if (!pi_state) + return -EINVAL; + ++ /* ++ * If current does not own the pi_state then the futex is ++ * inconsistent and user space fiddled with the futex value. ++ */ ++ if (pi_state->owner != current) ++ return -EINVAL; ++ + spin_lock(&pi_state->pi_mutex.wait_lock); + new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); + diff --git a/queue-2.6.32/futex_lock_pi-key-refcnt-fix.patch b/queue-2.6.32/futex_lock_pi-key-refcnt-fix.patch new file mode 100644 index 00000000000..52364522bd9 --- /dev/null +++ b/queue-2.6.32/futex_lock_pi-key-refcnt-fix.patch @@ -0,0 +1,51 @@ +From 5ecb01cfdf96c5f465192bdb2a4fd4a61a24c6cc Mon Sep 17 00:00:00 2001 +From: Mikael Pettersson +Date: Sat, 23 Jan 2010 22:36:29 +0100 +Subject: futex_lock_pi() key refcnt fix + +From: Mikael Pettersson + +commit 5ecb01cfdf96c5f465192bdb2a4fd4a61a24c6cc upstream. + +This fixes a futex key reference count bug in futex_lock_pi(), +where a key's reference count is incremented twice but decremented +only once, causing the backing object to not be released. + +If the futex is created in a temporary file in an ext3 file system, +this bug causes the file's inode to become an "undead" orphan, +which causes an oops from a BUG_ON() in ext3_put_super() when the +file system is unmounted. glibc's test suite is known to trigger this, +see . + +The bug is a regression from 2.6.28-git3, namely Peter Zijlstra's +38d47c1b7075bd7ec3881141bb3629da58f88dab "[PATCH] futex: rely on +get_user_pages() for shared futexes". That commit made get_futex_key() +also increment the reference count of the futex key, and updated its +callers to decrement the key's reference count before returning. +Unfortunately the normal exit path in futex_lock_pi() wasn't corrected: +the reference count is incremented by get_futex_key() and queue_lock(), +but the normal exit path only decrements once, via unqueue_me_pi(). +The fix is to put_futex_key() after unqueue_me_pi(), since 2.6.31 +this is easily done by 'goto out_put_key' rather than 'goto out'. + +Signed-off-by: Mikael Pettersson +Acked-by: Peter Zijlstra +Acked-by: Darren Hart +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1971,7 +1971,7 @@ retry_private: + /* Unqueue and drop the lock */ + unqueue_me_pi(&q); + +- goto out; ++ goto out_put_key; + + out_unlock_put_key: + queue_unlock(&q, hb); diff --git a/queue-2.6.32/series b/queue-2.6.32/series new file mode 100644 index 00000000000..277fdc08072 --- /dev/null +++ b/queue-2.6.32/series @@ -0,0 +1,5 @@ +fix-potential-crash-with-sys_move_pages.patch +futex_lock_pi-key-refcnt-fix.patch +futex-handle-user-space-corruption-gracefully.patch +futex-handle-futex-value-corruption-gracefully.patch +fix-race-in-tty_fasync-properly.patch