diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-01 16:36:31 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-01 16:36:31 +0900 |
commit | 2dabec14ce5d7411cbefc07531ac833363de25a0 (patch) | |
tree | 4c9f5b3cff00aa4f7147a3156101ecb7b937bb3d | |
parent | 86e1b5e084c2ceb283cb9e700ba620277170ed87 (diff) | |
download | stable-queue-2dabec14ce5d7411cbefc07531ac833363de25a0.tar.gz |
.38 patches
-rw-r--r-- | queue-2.6.38/ext4-fix-possible-use-after-free-in.patch | 48 | ||||
-rw-r--r-- | queue-2.6.38/ext4-use-schedule_timeout_interruptible-for-waiting-in.patch | 147 | ||||
-rw-r--r-- | queue-2.6.38/series | 2 |
3 files changed, 197 insertions, 0 deletions
diff --git a/queue-2.6.38/ext4-fix-possible-use-after-free-in.patch b/queue-2.6.38/ext4-fix-possible-use-after-free-in.patch new file mode 100644 index 0000000000..b185e4f117 --- /dev/null +++ b/queue-2.6.38/ext4-fix-possible-use-after-free-in.patch @@ -0,0 +1,48 @@ +From 1bb933fb1fa8e4cb337a0d5dfd2ff4c0dc2073e8 Mon Sep 17 00:00:00 2001 +From: Lukas Czerner <lczerner@redhat.com> +Date: Fri, 20 May 2011 13:55:29 -0400 +Subject: ext4: fix possible use-after-free in + ext4_remove_li_request() + +From: Lukas Czerner <lczerner@redhat.com> + +commit 1bb933fb1fa8e4cb337a0d5dfd2ff4c0dc2073e8 upstream. + +We need to take reference to the s_li_request after we take a mutex, +because it might be freed since then, hence result in accessing old +already freed memory. Also we should protect the whole +ext4_remove_li_request() because ext4_li_info might be in the process of +being freed in ext4_lazyinit_thread(). + +Signed-off-by: Lukas Czerner <lczerner@redhat.com> +Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> +Reviewed-by: Eric Sandeen <sandeen@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/ext4/super.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2716,14 +2716,16 @@ static void ext4_remove_li_request(struc + + static void ext4_unregister_li_request(struct super_block *sb) + { +- struct ext4_li_request *elr = EXT4_SB(sb)->s_li_request; +- +- if (!ext4_li_info) ++ mutex_lock(&ext4_li_mtx); ++ if (!ext4_li_info) { ++ mutex_unlock(&ext4_li_mtx); + return; ++ } + + mutex_lock(&ext4_li_info->li_list_mtx); +- ext4_remove_li_request(elr); ++ ext4_remove_li_request(EXT4_SB(sb)->s_li_request); + mutex_unlock(&ext4_li_info->li_list_mtx); ++ mutex_unlock(&ext4_li_mtx); + } + + static struct task_struct *ext4_lazyinit_task; diff --git a/queue-2.6.38/ext4-use-schedule_timeout_interruptible-for-waiting-in.patch b/queue-2.6.38/ext4-use-schedule_timeout_interruptible-for-waiting-in.patch new file mode 100644 index 0000000000..1c6de2eb16 --- /dev/null +++ b/queue-2.6.38/ext4-use-schedule_timeout_interruptible-for-waiting-in.patch @@ -0,0 +1,147 @@ +From 4ed5c033c11b33149d993734a6a8de1016e8f03f Mon Sep 17 00:00:00 2001 +From: Lukas Czerner <lczerner@redhat.com> +Date: Fri, 20 May 2011 13:49:04 -0400 +Subject: ext4: Use schedule_timeout_interruptible() for waiting in + lazyinit thread + +From: Lukas Czerner <lczerner@redhat.com> + +commit 4ed5c033c11b33149d993734a6a8de1016e8f03f upstream. + +In order to make lazyinit eat approx. 10% of io bandwidth at max, we +are sleeping between zeroing each single inode table. For that purpose +we are using timer which wakes up thread when it expires. It is set +via add_timer() and this may cause troubles in the case that thread +has been woken up earlier and in next iteration we call add_timer() on +still running timer hence hitting BUG_ON in add_timer(). We could fix +that by using mod_timer() instead however we can use +schedule_timeout_interruptible() for waiting and hence simplifying +things a lot. + +This commit exchange the old "waiting mechanism" with simple +schedule_timeout_interruptible(), setting the time to sleep. Hence we +do not longer need li_wait_daemon waiting queue and others, so get rid +of it. + +Addresses-Red-Hat-Bugzilla: #699708 + +Signed-off-by: Lukas Czerner <lczerner@redhat.com> +Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> +Reviewed-by: Eric Sandeen <sandeen@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/ext4/ext4.h | 4 ---- + fs/ext4/super.c | 31 ++++++------------------------- + 2 files changed, 6 insertions(+), 29 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1590,12 +1590,8 @@ void ext4_get_group_no_and_offset(struct + */ + struct ext4_lazy_init { + unsigned long li_state; +- +- wait_queue_head_t li_wait_daemon; + wait_queue_head_t li_wait_task; +- struct timer_list li_timer; + struct task_struct *li_task; +- + struct list_head li_request_list; + struct mutex li_list_mtx; + }; +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2645,12 +2645,6 @@ static void print_daily_error_info(unsig + mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ); /* Once a day */ + } + +-static void ext4_lazyinode_timeout(unsigned long data) +-{ +- struct task_struct *p = (struct task_struct *)data; +- wake_up_process(p); +-} +- + /* Find next suitable group and run ext4_init_inode_table */ + static int ext4_run_li_request(struct ext4_li_request *elr) + { +@@ -2698,7 +2692,7 @@ static int ext4_run_li_request(struct ex + + /* + * Remove lr_request from the list_request and free the +- * request tructure. Should be called with li_list_mtx held ++ * request structure. Should be called with li_list_mtx held + */ + static void ext4_remove_li_request(struct ext4_li_request *elr) + { +@@ -2744,14 +2738,10 @@ static int ext4_lazyinit_thread(void *ar + struct ext4_lazy_init *eli = (struct ext4_lazy_init *)arg; + struct list_head *pos, *n; + struct ext4_li_request *elr; +- unsigned long next_wakeup; +- DEFINE_WAIT(wait); ++ unsigned long next_wakeup, cur; + + BUG_ON(NULL == eli); + +- eli->li_timer.data = (unsigned long)current; +- eli->li_timer.function = ext4_lazyinode_timeout; +- + eli->li_task = current; + wake_up(&eli->li_wait_task); + +@@ -2785,19 +2775,15 @@ cont_thread: + if (freezing(current)) + refrigerator(); + +- if ((time_after_eq(jiffies, next_wakeup)) || ++ cur = jiffies; ++ if ((time_after_eq(cur, next_wakeup)) || + (MAX_JIFFY_OFFSET == next_wakeup)) { + cond_resched(); + continue; + } + +- eli->li_timer.expires = next_wakeup; +- add_timer(&eli->li_timer); +- prepare_to_wait(&eli->li_wait_daemon, &wait, +- TASK_INTERRUPTIBLE); +- if (time_before(jiffies, next_wakeup)) +- schedule(); +- finish_wait(&eli->li_wait_daemon, &wait); ++ schedule_timeout_interruptible(next_wakeup - cur); ++ + if (kthread_should_stop()) { + ext4_clear_request_list(); + goto exit_thread; +@@ -2821,12 +2807,10 @@ exit_thread: + goto cont_thread; + } + mutex_unlock(&eli->li_list_mtx); +- del_timer_sync(&ext4_li_info->li_timer); + eli->li_task = NULL; + wake_up(&eli->li_wait_task); + + kfree(ext4_li_info); +- ext4_lazyinit_task = NULL; + ext4_li_info = NULL; + mutex_unlock(&ext4_li_mtx); + +@@ -2854,7 +2838,6 @@ static int ext4_run_lazyinit_thread(void + if (IS_ERR(ext4_lazyinit_task)) { + int err = PTR_ERR(ext4_lazyinit_task); + ext4_clear_request_list(); +- del_timer_sync(&ext4_li_info->li_timer); + kfree(ext4_li_info); + ext4_li_info = NULL; + printk(KERN_CRIT "EXT4: error %d creating inode table " +@@ -2903,9 +2886,7 @@ static int ext4_li_info_new(void) + INIT_LIST_HEAD(&eli->li_request_list); + mutex_init(&eli->li_list_mtx); + +- init_waitqueue_head(&eli->li_wait_daemon); + init_waitqueue_head(&eli->li_wait_task); +- init_timer(&eli->li_timer); + eli->li_state |= EXT4_LAZYINIT_QUIT; + + ext4_li_info = eli; diff --git a/queue-2.6.38/series b/queue-2.6.38/series index e041aa73a4..7d619f39a5 100644 --- a/queue-2.6.38/series +++ b/queue-2.6.38/series @@ -30,6 +30,7 @@ block-always-allocate-genhd-ev-if-check_events-is.patch mtd-mtdconcat-fix-nand-oob-write.patch mtd-return-badblockbits-back.patch x86-64-bit-fix-copy__user-checks-for-the.patch +ext4-fix-possible-use-after-free-in.patch iwlwifi-fix-bugs-in-change_interface.patch nl80211-fix-set_key-regression-with-some-drivers.patch mac80211-fix-a-few-rcu-issues.patch @@ -141,3 +142,4 @@ nfsv4-handle-expired-stateids-when-the-lease-is-still-valid.patch nfsv4.1-fix-the-handling-of-nfs4err_seq_misordered-errors.patch pci-add-quirk-for-setting-valid-class-for-ti816x-endpoint.patch xen-mmu-fix-a-race-window-causing-leave_mm-bug.patch +ext4-use-schedule_timeout_interruptible-for-waiting-in.patch |