summaryrefslogtreecommitdiff
path: root/sys-kernel/cairn-sources/files/5.10.7/hardened-patches/0056-slub-Add-support-for-verifying-slab-sanitization.patch
diff options
context:
space:
mode:
Diffstat (limited to 'sys-kernel/cairn-sources/files/5.10.7/hardened-patches/0056-slub-Add-support-for-verifying-slab-sanitization.patch')
-rw-r--r--sys-kernel/cairn-sources/files/5.10.7/hardened-patches/0056-slub-Add-support-for-verifying-slab-sanitization.patch116
1 files changed, 116 insertions, 0 deletions
diff --git a/sys-kernel/cairn-sources/files/5.10.7/hardened-patches/0056-slub-Add-support-for-verifying-slab-sanitization.patch b/sys-kernel/cairn-sources/files/5.10.7/hardened-patches/0056-slub-Add-support-for-verifying-slab-sanitization.patch
new file mode 100644
index 000000000000..88a26f6c5358
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.7/hardened-patches/0056-slub-Add-support-for-verifying-slab-sanitization.patch
@@ -0,0 +1,116 @@
+From 0df4718423ec96eb9397a9eef554c4cabf2ecc09 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 15:58:57 -0400
+Subject: [PATCH 056/113] slub: Add support for verifying slab sanitization
+
+This is an extension to the sanitization feature in PaX for when
+sacricifing more performance for security is acceptable.
+
+The initial version from Daniel Micay was relying on PAGE_SANITIZE. It
+now relies on upstream's init_on_free.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ mm/slub.c | 36 ++++++++++++++++++++++++++++++++----
+ security/Kconfig.hardening | 8 ++++++++
+ 2 files changed, 40 insertions(+), 4 deletions(-)
+
+diff --git a/mm/slub.c b/mm/slub.c
+index cf24f74e01de..d42d2709526a 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -127,6 +127,12 @@ static inline bool kmem_cache_debug(struct kmem_cache *s)
+ return kmem_cache_debug_flags(s, SLAB_DEBUG_FLAGS);
+ }
+
++static inline bool has_sanitize_verify(struct kmem_cache *s)
++{
++ return IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) &&
++ slab_want_init_on_free(s);
++}
++
+ void *fixup_red_left(struct kmem_cache *s, void *p)
+ {
+ if (kmem_cache_debug_flags(s, SLAB_RED_ZONE))
+@@ -1571,7 +1577,7 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ : 0;
+ memset((char *)object + s->inuse, 0,
+ s->size - s->inuse - rsize);
+- if (s->ctor)
++ if (!IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) && s->ctor)
+ s->ctor(object);
+ }
+ /* If object's reuse doesn't have to be delayed */
+@@ -1606,7 +1612,7 @@ static void *setup_object(struct kmem_cache *s, struct page *page,
+ {
+ setup_object_debug(s, page, object);
+ object = kasan_init_slab_obj(s, object);
+- if (unlikely(s->ctor)) {
++ if (unlikely(s->ctor) && !has_sanitize_verify(s)) {
+ kasan_unpoison_object_data(s, object);
+ s->ctor(object);
+ kasan_poison_object_data(s, object);
+@@ -2897,7 +2903,16 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
+
+ maybe_wipe_obj_freeptr(s, object);
+
+- if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
++ if (has_sanitize_verify(s) && object) {
++ /* KASAN hasn't unpoisoned the object yet (this is done in the
++ * post-alloc hook), so let's do it temporarily.
++ */
++ kasan_unpoison_object_data(s, object);
++ BUG_ON(memchr_inv(object, 0, s->object_size));
++ if (s->ctor)
++ s->ctor(object);
++ kasan_poison_object_data(s, object);
++ } else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
+ memset(object, 0, s->object_size);
+
+ slab_post_alloc_hook(s, objcg, gfpflags, 1, &object);
+@@ -3337,7 +3352,20 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
+ local_irq_enable();
+
+ /* Clear memory outside IRQ disabled fastpath loop */
+- if (unlikely(slab_want_init_on_alloc(flags, s))) {
++ if (has_sanitize_verify(s)) {
++ int j;
++
++ for (j = 0; j < i; j++) {
++ /* KASAN hasn't unpoisoned the object yet (this is done
++ * in the post-alloc hook), so let's do it temporarily.
++ */
++ kasan_unpoison_object_data(s, p[j]);
++ BUG_ON(memchr_inv(p[j], 0, s->object_size));
++ if (s->ctor)
++ s->ctor(p[j]);
++ kasan_poison_object_data(s, p[j]);
++ }
++ } else if (unlikely(slab_want_init_on_alloc(flags, s))) {
+ int j;
+
+ for (j = 0; j < i; j++)
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 3d2f1d2c3d80..a718487ad717 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -224,6 +224,14 @@ config PAGE_SANITIZE_VERIFY
+ When init_on_free is enabled, verify that newly allocated pages
+ are zeroed to detect write-after-free bugs.
+
++config SLAB_SANITIZE_VERIFY
++ bool "Verify sanitized SLAB allocations"
++ default y
++ depends on !KASAN
++ help
++ When init_on_free is enabled, verify that newly allocated slab
++ objects are zeroed to detect write-after-free bugs.
++
+ endmenu
+
+ endmenu
+--
+2.30.0
+