diff options
| -rw-r--r-- | include/linux/kasan.h | 6 | ||||
| -rw-r--r-- | mm/kasan/kasan.c | 20 |
2 files changed, 25 insertions, 1 deletions
diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 4b9f85c963d0..0fdc798e3ff7 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _LINUX_KASAN_H | 1 | #ifndef _LINUX_KASAN_H |
| 2 | #define _LINUX_KASAN_H | 2 | #define _LINUX_KASAN_H |
| 3 | 3 | ||
| 4 | #include <linux/sched.h> | ||
| 4 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 5 | 6 | ||
| 6 | struct kmem_cache; | 7 | struct kmem_cache; |
| @@ -13,7 +14,6 @@ struct vm_struct; | |||
| 13 | 14 | ||
| 14 | #include <asm/kasan.h> | 15 | #include <asm/kasan.h> |
| 15 | #include <asm/pgtable.h> | 16 | #include <asm/pgtable.h> |
| 16 | #include <linux/sched.h> | ||
| 17 | 17 | ||
| 18 | extern unsigned char kasan_zero_page[PAGE_SIZE]; | 18 | extern unsigned char kasan_zero_page[PAGE_SIZE]; |
| 19 | extern pte_t kasan_zero_pte[PTRS_PER_PTE]; | 19 | extern pte_t kasan_zero_pte[PTRS_PER_PTE]; |
| @@ -43,6 +43,8 @@ static inline void kasan_disable_current(void) | |||
| 43 | 43 | ||
| 44 | void kasan_unpoison_shadow(const void *address, size_t size); | 44 | void kasan_unpoison_shadow(const void *address, size_t size); |
| 45 | 45 | ||
| 46 | void kasan_unpoison_task_stack(struct task_struct *task); | ||
| 47 | |||
| 46 | void kasan_alloc_pages(struct page *page, unsigned int order); | 48 | void kasan_alloc_pages(struct page *page, unsigned int order); |
| 47 | void kasan_free_pages(struct page *page, unsigned int order); | 49 | void kasan_free_pages(struct page *page, unsigned int order); |
| 48 | 50 | ||
| @@ -66,6 +68,8 @@ void kasan_free_shadow(const struct vm_struct *vm); | |||
| 66 | 68 | ||
| 67 | static inline void kasan_unpoison_shadow(const void *address, size_t size) {} | 69 | static inline void kasan_unpoison_shadow(const void *address, size_t size) {} |
| 68 | 70 | ||
| 71 | static inline void kasan_unpoison_task_stack(struct task_struct *task) {} | ||
| 72 | |||
| 69 | static inline void kasan_enable_current(void) {} | 73 | static inline void kasan_enable_current(void) {} |
| 70 | static inline void kasan_disable_current(void) {} | 74 | static inline void kasan_disable_current(void) {} |
| 71 | 75 | ||
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c index bc0a8d8b8f42..1ad20ade8c91 100644 --- a/mm/kasan/kasan.c +++ b/mm/kasan/kasan.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/kmemleak.h> | 22 | #include <linux/kmemleak.h> |
| 23 | #include <linux/linkage.h> | ||
| 23 | #include <linux/memblock.h> | 24 | #include <linux/memblock.h> |
| 24 | #include <linux/memory.h> | 25 | #include <linux/memory.h> |
| 25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| @@ -60,6 +61,25 @@ void kasan_unpoison_shadow(const void *address, size_t size) | |||
| 60 | } | 61 | } |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 64 | static void __kasan_unpoison_stack(struct task_struct *task, void *sp) | ||
| 65 | { | ||
| 66 | void *base = task_stack_page(task); | ||
| 67 | size_t size = sp - base; | ||
| 68 | |||
| 69 | kasan_unpoison_shadow(base, size); | ||
| 70 | } | ||
| 71 | |||
| 72 | /* Unpoison the entire stack for a task. */ | ||
| 73 | void kasan_unpoison_task_stack(struct task_struct *task) | ||
| 74 | { | ||
| 75 | __kasan_unpoison_stack(task, task_stack_page(task) + THREAD_SIZE); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Unpoison the stack for the current task beyond a watermark sp value. */ | ||
| 79 | asmlinkage void kasan_unpoison_remaining_stack(void *sp) | ||
| 80 | { | ||
| 81 | __kasan_unpoison_stack(current, sp); | ||
| 82 | } | ||
| 63 | 83 | ||
| 64 | /* | 84 | /* |
| 65 | * All functions below always inlined so compiler could | 85 | * All functions below always inlined so compiler could |
