We saw crashes where slub percpu freelist was corrupted, this may catch
the problem earlier where we first time see bad freelist, and suppress
further corruption.

This is enabled with 'slub_debug=F'.

https://virtuozzo.atlassian.net/browse/PSBM-155867

Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com>
---
v2: fixed compilation in case !CONFIG_SLUB_DEBUG
---
 mm/slub.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/mm/slub.c b/mm/slub.c
index d4392708a0148..748a4a036ff35 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1085,6 +1085,20 @@ static void setup_object_debug(struct kmem_cache *s, 
struct page *page,
        init_tracking(s, object);
 }
 
+
+static inline int alloc_valid_pointer_check(struct kmem_cache *s,
+                                           struct page *page, void *object)
+{
+       if (s->flags & SLAB_CONSISTENCY_CHECKS &&
+           !check_valid_pointer(s, page, object)) {
+               if (printk_ratelimit())
+                       object_err(s, page, object, "Freelist Pointer 
corrupted");
+               return 0;
+       }
+
+       return 1;
+}
+
 static inline int alloc_consistency_checks(struct kmem_cache *s, struct page 
*page,
                                        void *object)
 {
@@ -1343,6 +1357,10 @@ static unsigned long kmem_cache_flags(unsigned long 
object_size,
 static inline void setup_object_debug(struct kmem_cache *s,
                        struct page *page, void *object) {}
 
+static inline int alloc_valid_pointer_check(struct kmem_cache *s,
+                                           struct page *page,
+                                           void *object) { return 0; }
+
 static inline int alloc_debug_processing(struct kmem_cache *s,
        struct page *page, void *object, unsigned long addr) { return 0; }
 
@@ -2517,6 +2535,10 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t 
gfpflags, int node,
         * That page must be frozen for per cpu allocations to work.
         */
        VM_BUG_ON(!c->page->frozen);
+
+       if (kmem_cache_debug(s) && !alloc_valid_pointer_check(s, c->page, 
freelist))
+               return NULL;
+
        c->freelist = get_freepointer(s, freelist);
        c->tid = next_tid(c->tid);
        return freelist;
-- 
2.45.2

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to