mm: kasan: initial memory quarantine implementation
[cascardo/linux.git] / mm / kasan / kasan.h
index 4f6c62e..7f7ac51 100644 (file)
@@ -2,6 +2,7 @@
 #define __MM_KASAN_KASAN_H
 
 #include <linux/kasan.h>
+#include <linux/stackdepot.h>
 
 #define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT)
 #define KASAN_SHADOW_MASK       (KASAN_SHADOW_SCALE_SIZE - 1)
@@ -54,6 +55,48 @@ struct kasan_global {
 #endif
 };
 
+/**
+ * Structures to keep alloc and free tracks *
+ */
+
+enum kasan_state {
+       KASAN_STATE_INIT,
+       KASAN_STATE_ALLOC,
+       KASAN_STATE_QUARANTINE,
+       KASAN_STATE_FREE
+};
+
+#define KASAN_STACK_DEPTH 64
+
+struct kasan_track {
+       u32 pid;
+       depot_stack_handle_t stack;
+};
+
+struct kasan_alloc_meta {
+       struct kasan_track track;
+       u32 state : 2;  /* enum kasan_state */
+       u32 alloc_size : 30;
+       u32 reserved;
+};
+
+struct qlist_node {
+       struct qlist_node *next;
+};
+struct kasan_free_meta {
+       /* This field is used while the object is in the quarantine.
+        * Otherwise it might be used for the allocator freelist.
+        */
+       struct qlist_node quarantine_link;
+       struct kasan_track track;
+};
+
+struct kasan_alloc_meta *get_alloc_info(struct kmem_cache *cache,
+                                       const void *object);
+struct kasan_free_meta *get_free_info(struct kmem_cache *cache,
+                                       const void *object);
+
+
 static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
 {
        return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
@@ -68,4 +111,15 @@ static inline bool kasan_report_enabled(void)
 void kasan_report(unsigned long addr, size_t size,
                bool is_write, unsigned long ip);
 
+#ifdef CONFIG_SLAB
+void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache);
+void quarantine_reduce(void);
+void quarantine_remove_cache(struct kmem_cache *cache);
+#else
+static inline void quarantine_put(struct kasan_free_meta *info,
+                               struct kmem_cache *cache) { }
+static inline void quarantine_reduce(void) { }
+static inline void quarantine_remove_cache(struct kmem_cache *cache) { }
+#endif
+
 #endif