Message ID | 1308750171-12578-1-git-send-email-stefan.bader@canonical.com |
---|---|
State | New |
Headers | show |
On 06/22/2011 07:42 AM, Stefan Bader wrote: > After Andy's feedback and looking a bit closer to what the 2.6.24 > version of the file looks like, it seems that it is probably better > to refrain from changing too much code. > > IOW it is better to look like 2.6.24 than like the 2.6.18 xen repo > we can check against. > > This does actually reduce the changes to a few things that are much > simpler to look at. So I split the changes into three indipendant > findings. The first two are more theoretical but probably best fixed > right now when I remember. > > The last one is the actual issue in pgd_dtor. > > -Stefan > > From e06452cbeb90be8fa2cb8752c6661b7443e5f834 Mon Sep 17 00:00:00 2001 > From: Stefan Bader<stefan.bader@canonical.com> > Date: Wed, 22 Jun 2011 14:34:18 +0200 > Subject: [PATCH] UBUNTU: xen: Fix memory corruption caused by double free > > The Xen patches missed to exclude a section in pgd_dtor which causes > pgds which are freed on a quicklist trim to be unlinked from the > pgd_list for a second time. This causes memory coruption in struct pages > which possible are not even related to pgds. > > Beside of this, a possible NULL pointer access and potential unbalanced > function call to xen_destroy_region get fixed. > > BugLink: http://bugs.launchpad.net/bugs/705562 > > Signed-off-by: Stefan Bader<stefan.bader@canonical.com> > --- > ...n-Check-for-NULL-pointer-before-using-pgd.patch | 37 +++++++++++++++++ > ...xen_destroy_contiguous_region-only-needed.patch | 37 +++++++++++++++++ > ...Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch | 43 ++++++++++++++++++++ > 3 files changed, 117 insertions(+), 0 deletions(-) > create mode 100644 debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch > create mode 100644 debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch > create mode 100644 debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch > > diff --git a/debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch b/debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch > new file mode 100644 > index 0000000..5faf99a > --- /dev/null > +++ b/debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch > @@ -0,0 +1,37 @@ > +From 310f9650b26f889008ae5210ed7cadb9dcb5e39f Mon Sep 17 00:00:00 2001 > +From: Stefan Bader<stefan.bader@canonical.com> > +Date: Tue, 21 Jun 2011 09:48:56 +0200 > +Subject: [PATCH 21/23] UBUNTU: xen: Check for NULL pointer before using pgd > + > +In pgd_alloc(), the test for the new pgd being NULL is done > +after it has already been used for test_and_unpin(). Do that > +check before. > + > +BugLink: http://bugs.launchpad.net/bugs/705562 > + > +Signed-off-by: Stefan Bader<stefan.bader@canonical.com> > +--- > + arch/x86/mm/pgtable_32-xen.c | 5 ++++- > + 1 files changed, 4 insertions(+), 1 deletions(-) > + > +diff --git a/arch/x86/mm/pgtable_32-xen.c b/arch/x86/mm/pgtable_32-xen.c > +index 74a2e57..48242aa 100644 > +--- a/arch/x86/mm/pgtable_32-xen.c > ++++ b/arch/x86/mm/pgtable_32-xen.c > +@@ -345,9 +345,12 @@ pgd_t *pgd_alloc(struct mm_struct *mm) > + pmd_t **pmds = NULL; > + unsigned long flags; > + > ++ if (!pgd) > ++ return NULL; > ++ > + pgd_test_and_unpin(pgd); > + > +- if (PTRS_PER_PMD == 1 || !pgd) > ++ if (PTRS_PER_PMD == 1) > + return pgd; > + > + #ifdef CONFIG_XEN > +-- > +1.7.4.1 > + > diff --git a/debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch b/debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch > new file mode 100644 > index 0000000..bb3670a > --- /dev/null > +++ b/debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch > @@ -0,0 +1,37 @@ > +From 6a622c376c715a04d245bb3ca1f7910680b8165c Mon Sep 17 00:00:00 2001 > +From: Stefan Bader<stefan.bader@canonical.com> > +Date: Wed, 22 Jun 2011 12:06:51 +0200 > +Subject: [PATCH 22/23] UBUNTU: xen: xen_destroy_contiguous_region only needed in unshared case > + > +The call to create is only done for !SHARED_KERNEL_PMD, so only destroy > +in that case (also this is only useful when CONFIG_XEN is set. > + > +BugLink: http://bugs.launchpad.net/bugs/705562 > + > +Signed-off-by: Stefan Bader<stefan.bader@canonical.com> > +--- > + arch/x86/mm/pgtable_32-xen.c | 8 ++++++-- > + 1 files changed, 6 insertions(+), 2 deletions(-) > + > +diff --git a/arch/x86/mm/pgtable_32-xen.c b/arch/x86/mm/pgtable_32-xen.c > +index 48242aa..49e28e7 100644 > +--- a/arch/x86/mm/pgtable_32-xen.c > ++++ b/arch/x86/mm/pgtable_32-xen.c > +@@ -473,8 +473,12 @@ void pgd_free(pgd_t *pgd) > + pmd_cache_free(pmd, i); > + } > + > +- if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) > +- xen_destroy_contiguous_region((unsigned long)pgd, 0); > ++#ifdef CONFIG_XEN > ++ if (!SHARED_KERNEL_PMD) > ++ if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) > ++ xen_destroy_contiguous_region( > ++ (unsigned long)pgd, 0); > ++#endif > + } > + > + /* in the non-PAE case, free_pgtables() clears user pgd entries */ > +-- > +1.7.4.1 > + > diff --git a/debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch b/debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch > new file mode 100644 > index 0000000..0c65d36 > --- /dev/null > +++ b/debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch > @@ -0,0 +1,43 @@ > +From b70dad384c6b97b30a11838989364bb5946922cf Mon Sep 17 00:00:00 2001 > +From: Stefan Bader<stefan.bader@canonical.com> > +Date: Wed, 22 Jun 2011 12:16:10 +0200 > +Subject: [PATCH 23/23] UBUNTU: xen: Do not call pgd_list_del in pgd_dtor for Xen > + > +The Xen modifications add code to remove the pgd from the list as soon > +as it is freed in pgd_free. > + > +BugLink: http://bugs.launchpad.net/bugs/705562 > + > +Signed-off-by: Stefan Bader<stefan.bader@canonical.com> > +--- > + arch/x86/mm/pgtable_32-xen.c | 5 +++++ > + 1 files changed, 5 insertions(+), 0 deletions(-) > + > +diff --git a/arch/x86/mm/pgtable_32-xen.c b/arch/x86/mm/pgtable_32-xen.c > +index 49e28e7..d8bc211 100644 > +--- a/arch/x86/mm/pgtable_32-xen.c > ++++ b/arch/x86/mm/pgtable_32-xen.c > +@@ -290,15 +290,20 @@ static void pgd_ctor(void *pgd) > + > + static void pgd_dtor(void *pgd) > + { > ++#ifndef CONFIG_XEN > + unsigned long flags; /* can be called from interrupt context */ > ++#endif > + > + if (SHARED_KERNEL_PMD) > + return; > + > ++#ifndef CONFIG_XEN > ++ /* This is done in pgd_free in the Xen case. */ > + paravirt_release_pd(__pa(pgd)>> PAGE_SHIFT); > + spin_lock_irqsave(&pgd_lock, flags); > + pgd_list_del(pgd); > + spin_unlock_irqrestore(&pgd_lock, flags); > ++#endif > + > + pgd_test_and_unpin(pgd); > + } > +-- > +1.7.4.1 > +
diff --git a/debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch b/debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch new file mode 100644 index 0000000..5faf99a --- /dev/null +++ b/debian/binary-custom.d/xen/patchset/022-UBUNTU-xen-Check-for-NULL-pointer-before-using-pgd.patch @@ -0,0 +1,37 @@ +From 310f9650b26f889008ae5210ed7cadb9dcb5e39f Mon Sep 17 00:00:00 2001 +From: Stefan Bader <stefan.bader@canonical.com> +Date: Tue, 21 Jun 2011 09:48:56 +0200 +Subject: [PATCH 21/23] UBUNTU: xen: Check for NULL pointer before using pgd + +In pgd_alloc(), the test for the new pgd being NULL is done +after it has already been used for test_and_unpin(). Do that +check before. + +BugLink: http://bugs.launchpad.net/bugs/705562 + +Signed-off-by: Stefan Bader <stefan.bader@canonical.com> +--- + arch/x86/mm/pgtable_32-xen.c | 5 ++++- + 1 files changed, 4 insertions(+), 1 deletions(-) + +diff --git a/arch/x86/mm/pgtable_32-xen.c b/arch/x86/mm/pgtable_32-xen.c +index 74a2e57..48242aa 100644 +--- a/arch/x86/mm/pgtable_32-xen.c ++++ b/arch/x86/mm/pgtable_32-xen.c +@@ -345,9 +345,12 @@ pgd_t *pgd_alloc(struct mm_struct *mm) + pmd_t **pmds = NULL; + unsigned long flags; + ++ if (!pgd) ++ return NULL; ++ + pgd_test_and_unpin(pgd); + +- if (PTRS_PER_PMD == 1 || !pgd) ++ if (PTRS_PER_PMD == 1) + return pgd; + + #ifdef CONFIG_XEN +-- +1.7.4.1 + diff --git a/debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch b/debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch new file mode 100644 index 0000000..bb3670a --- /dev/null +++ b/debian/binary-custom.d/xen/patchset/023-UBUNTU-xen-xen_destroy_contiguous_region-only-needed.patch @@ -0,0 +1,37 @@ +From 6a622c376c715a04d245bb3ca1f7910680b8165c Mon Sep 17 00:00:00 2001 +From: Stefan Bader <stefan.bader@canonical.com> +Date: Wed, 22 Jun 2011 12:06:51 +0200 +Subject: [PATCH 22/23] UBUNTU: xen: xen_destroy_contiguous_region only needed in unshared case + +The call to create is only done for !SHARED_KERNEL_PMD, so only destroy +in that case (also this is only useful when CONFIG_XEN is set. + +BugLink: http://bugs.launchpad.net/bugs/705562 + +Signed-off-by: Stefan Bader <stefan.bader@canonical.com> +--- + arch/x86/mm/pgtable_32-xen.c | 8 ++++++-- + 1 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/mm/pgtable_32-xen.c b/arch/x86/mm/pgtable_32-xen.c +index 48242aa..49e28e7 100644 +--- a/arch/x86/mm/pgtable_32-xen.c ++++ b/arch/x86/mm/pgtable_32-xen.c +@@ -473,8 +473,12 @@ void pgd_free(pgd_t *pgd) + pmd_cache_free(pmd, i); + } + +- if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) +- xen_destroy_contiguous_region((unsigned long)pgd, 0); ++#ifdef CONFIG_XEN ++ if (!SHARED_KERNEL_PMD) ++ if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) ++ xen_destroy_contiguous_region( ++ (unsigned long)pgd, 0); ++#endif + } + + /* in the non-PAE case, free_pgtables() clears user pgd entries */ +-- +1.7.4.1 + diff --git a/debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch b/debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch new file mode 100644 index 0000000..0c65d36 --- /dev/null +++ b/debian/binary-custom.d/xen/patchset/024-UBUNTU-xen-Do-not-call-pgd_list_del-in-pgd_dtor-for-.patch @@ -0,0 +1,43 @@ +From b70dad384c6b97b30a11838989364bb5946922cf Mon Sep 17 00:00:00 2001 +From: Stefan Bader <stefan.bader@canonical.com> +Date: Wed, 22 Jun 2011 12:16:10 +0200 +Subject: [PATCH 23/23] UBUNTU: xen: Do not call pgd_list_del in pgd_dtor for Xen + +The Xen modifications add code to remove the pgd from the list as soon +as it is freed in pgd_free. + +BugLink: http://bugs.launchpad.net/bugs/705562 + +Signed-off-by: Stefan Bader <stefan.bader@canonical.com> +--- + arch/x86/mm/pgtable_32-xen.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/arch/x86/mm/pgtable_32-xen.c b/arch/x86/mm/pgtable_32-xen.c +index 49e28e7..d8bc211 100644 +--- a/arch/x86/mm/pgtable_32-xen.c ++++ b/arch/x86/mm/pgtable_32-xen.c +@@ -290,15 +290,20 @@ static void pgd_ctor(void *pgd) + + static void pgd_dtor(void *pgd) + { ++#ifndef CONFIG_XEN + unsigned long flags; /* can be called from interrupt context */ ++#endif + + if (SHARED_KERNEL_PMD) + return; + ++#ifndef CONFIG_XEN ++ /* This is done in pgd_free in the Xen case. */ + paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT); + spin_lock_irqsave(&pgd_lock, flags); + pgd_list_del(pgd); + spin_unlock_irqrestore(&pgd_lock, flags); ++#endif + + pgd_test_and_unpin(pgd); + } +-- +1.7.4.1 +