diff options
| author | Tony Luck <tony.luck@intel.com> | 2016-04-06 04:05:16 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-04-13 04:54:00 -0400 |
| commit | a3125494cff084b098c80bb36fbe2061ffed9d52 (patch) | |
| tree | 25d862d9e4b129f3b3cddf7bfcc7bc4bb120fdca /arch/x86/kernel/cpu/mcheck | |
| parent | f87e0434a3bedeb5e4d75d96d9f3ad424dae6b33 (diff) | |
x86/mce: Avoid using object after free in genpool
When we loop over all queued machine check error records to pass them
to the registered notifiers we use llist_for_each_entry(). But the loop
calls gen_pool_free() for the entry in the body of the loop - and then
the iterator looks at node->next after the free.
Use llist_for_each_entry_safe() instead.
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: <stable@vger.kernel.org>
Cc: Gong Chen <gong.chen@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: http://lkml.kernel.org/r/0205920@agluck-desk.sc.intel.com
Link: http://lkml.kernel.org/r/1459929916-12852-4-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck')
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-genpool.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-genpool.c b/arch/x86/kernel/cpu/mcheck/mce-genpool.c index 0a850100c594..2658e2af74ec 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-genpool.c +++ b/arch/x86/kernel/cpu/mcheck/mce-genpool.c | |||
| @@ -29,7 +29,7 @@ static char gen_pool_buf[MCE_POOLSZ]; | |||
| 29 | void mce_gen_pool_process(void) | 29 | void mce_gen_pool_process(void) |
| 30 | { | 30 | { |
| 31 | struct llist_node *head; | 31 | struct llist_node *head; |
| 32 | struct mce_evt_llist *node; | 32 | struct mce_evt_llist *node, *tmp; |
| 33 | struct mce *mce; | 33 | struct mce *mce; |
| 34 | 34 | ||
| 35 | head = llist_del_all(&mce_event_llist); | 35 | head = llist_del_all(&mce_event_llist); |
| @@ -37,7 +37,7 @@ void mce_gen_pool_process(void) | |||
| 37 | return; | 37 | return; |
| 38 | 38 | ||
| 39 | head = llist_reverse_order(head); | 39 | head = llist_reverse_order(head); |
| 40 | llist_for_each_entry(node, head, llnode) { | 40 | llist_for_each_entry_safe(node, tmp, head, llnode) { |
| 41 | mce = &node->mce; | 41 | mce = &node->mce; |
| 42 | atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); | 42 | atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); |
| 43 | gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); | 43 | gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); |
