diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-01 16:59:28 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-01 16:59:28 -0700 |
commit | f64ea63cf80428c8cb62b9aa13c3c27300b06bb8 (patch) | |
tree | 3e3a009b0d6bca54ef10667ac6d4338e6130a679 | |
parent | fe23f435f0d5e0d20c05c5a0f75ef27c7c0ecbf2 (diff) | |
download | longterm-queue-2.6.32-f64ea63cf80428c8cb62b9aa13c3c27300b06bb8.tar.gz |
.32 patches
-rw-r--r-- | queue-2.6.32/ksm-fix-null-pointer-dereference-in.patch | 85 | ||||
-rw-r--r-- | queue-2.6.32/migrate-don-t-account-swapcache-as-shmem.patch | 36 | ||||
-rw-r--r-- | queue-2.6.32/series | 2 |
3 files changed, 123 insertions, 0 deletions
diff --git a/queue-2.6.32/ksm-fix-null-pointer-dereference-in.patch b/queue-2.6.32/ksm-fix-null-pointer-dereference-in.patch new file mode 100644 index 0000000..62944e6 --- /dev/null +++ b/queue-2.6.32/ksm-fix-null-pointer-dereference-in.patch @@ -0,0 +1,85 @@ +From 2b472611a32a72f4a118c069c2d62a1a3f087afd Mon Sep 17 00:00:00 2001 +From: Hugh Dickins <hughd@google.com> +Date: Wed, 15 Jun 2011 15:08:58 -0700 +Subject: ksm: fix NULL pointer dereference in + scan_get_next_rmap_item() + +From: Hugh Dickins <hughd@google.com> + +commit 2b472611a32a72f4a118c069c2d62a1a3f087afd upstream. + +Andrea Righi reported a case where an exiting task can race against +ksmd::scan_get_next_rmap_item (http://lkml.org/lkml/2011/6/1/742) easily +triggering a NULL pointer dereference in ksmd. + +ksm_scan.mm_slot == &ksm_mm_head with only one registered mm + +CPU 1 (__ksm_exit) CPU 2 (scan_get_next_rmap_item) + list_empty() is false +lock slot == &ksm_mm_head +list_del(slot->mm_list) +(list now empty) +unlock + lock + slot = list_entry(slot->mm_list.next) + (list is empty, so slot is still ksm_mm_head) + unlock + slot->mm == NULL ... Oops + +Close this race by revalidating that the new slot is not simply the list +head again. + +Andrea's test case: + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> + +#define BUFSIZE getpagesize() + +int main(int argc, char **argv) +{ + void *ptr; + + if (posix_memalign(&ptr, getpagesize(), BUFSIZE) < 0) { + perror("posix_memalign"); + exit(1); + } + if (madvise(ptr, BUFSIZE, MADV_MERGEABLE) < 0) { + perror("madvise"); + exit(1); + } + *(char *)NULL = 0; + + return 0; +} + +Reported-by: Andrea Righi <andrea@betterlinux.com> +Tested-by: Andrea Righi <andrea@betterlinux.com> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Signed-off-by: Hugh Dickins <hughd@google.com> +Signed-off-by: Chris Wright <chrisw@sous-sol.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + mm/ksm.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -1215,6 +1215,12 @@ static struct rmap_item *scan_get_next_r + slot = list_entry(slot->mm_list.next, struct mm_slot, mm_list); + ksm_scan.mm_slot = slot; + spin_unlock(&ksm_mmlist_lock); ++ /* ++ * Although we tested list_empty() above, a racing __ksm_exit ++ * of the last mm on the list may have removed it since then. ++ */ ++ if (slot == &ksm_mm_head) ++ return NULL; + next_mm: + ksm_scan.address = 0; + ksm_scan.rmap_item = list_entry(&slot->rmap_list, diff --git a/queue-2.6.32/migrate-don-t-account-swapcache-as-shmem.patch b/queue-2.6.32/migrate-don-t-account-swapcache-as-shmem.patch new file mode 100644 index 0000000..481b676 --- /dev/null +++ b/queue-2.6.32/migrate-don-t-account-swapcache-as-shmem.patch @@ -0,0 +1,36 @@ +From 99a15e21d96f6857dafab1e5167e5e8183215c9c Mon Sep 17 00:00:00 2001 +From: Andrea Arcangeli <aarcange@redhat.com> +Date: Thu, 16 Jun 2011 12:56:19 -0700 +Subject: migrate: don't account swapcache as shmem + +From: Andrea Arcangeli <aarcange@redhat.com> + +commit 99a15e21d96f6857dafab1e5167e5e8183215c9c upstream. + +swapcache will reach the below code path in migrate_page_move_mapping, +and swapcache is accounted as NR_FILE_PAGES but it's not accounted as +NR_SHMEM. + +Hugh pointed out we must use PageSwapCache instead of comparing +mapping to &swapper_space, to avoid build failure with CONFIG_SWAP=n. + +Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> +Acked-by: Hugh Dickins <hughd@google.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + mm/migrate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -314,7 +314,7 @@ static int migrate_page_move_mapping(str + */ + __dec_zone_page_state(page, NR_FILE_PAGES); + __inc_zone_page_state(newpage, NR_FILE_PAGES); +- if (PageSwapBacked(page)) { ++ if (!PageSwapCache(page) && PageSwapBacked(page)) { + __dec_zone_page_state(page, NR_SHMEM); + __inc_zone_page_state(newpage, NR_SHMEM); + } diff --git a/queue-2.6.32/series b/queue-2.6.32/series new file mode 100644 index 0000000..2333b68 --- /dev/null +++ b/queue-2.6.32/series @@ -0,0 +1,2 @@ +ksm-fix-null-pointer-dereference-in.patch +migrate-don-t-account-swapcache-as-shmem.patch |