| From: Alexander Potapenko <glider@google.com> |
| Subject: lib/stackdepot: kmsan: mark API outputs as initialized |
| Date: Mon, 6 Mar 2023 12:13:21 +0100 |
| |
| KMSAN does not instrument stackdepot and may treat memory allocated by it |
| as uninitialized. This is not a problem for KMSAN itself, because its |
| functions calling stackdepot API are also not instrumented. But other |
| kernel features (e.g. netdev tracker) may access stack depot from |
| instrumented code, which will lead to false positives, unless we |
| explicitly mark stackdepot outputs as initialized. |
| |
| Link: https://lkml.kernel.org/r/20230306111322.205724-1-glider@google.com |
| Signed-off-by: Alexander Potapenko <glider@google.com> |
| Reported-by: syzbot <syzkaller@googlegroups.com> |
| Reviewed-by: Dmitry Vyukov <dvyukov@google.com> |
| Suggested-by: Dmitry Vyukov <dvyukov@google.com> |
| Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> |
| Cc: Marco Elver <elver@google.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| lib/stackdepot.c | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| --- a/lib/stackdepot.c~lib-stackdepot-kmsan-mark-api-outputs-as-initialized |
| +++ a/lib/stackdepot.c |
| @@ -17,6 +17,7 @@ |
| #include <linux/gfp.h> |
| #include <linux/jhash.h> |
| #include <linux/kernel.h> |
| +#include <linux/kmsan.h> |
| #include <linux/mm.h> |
| #include <linux/mutex.h> |
| #include <linux/percpu.h> |
| @@ -306,6 +307,11 @@ depot_alloc_stack(unsigned long *entries |
| stack->handle.extra = 0; |
| memcpy(stack->entries, entries, flex_array_size(stack, entries, size)); |
| pool_offset += required_size; |
| + /* |
| + * Let KMSAN know the stored stack record is initialized. This shall |
| + * prevent false positive reports if instrumented code accesses it. |
| + */ |
| + kmsan_unpoison_memory(stack, required_size); |
| |
| return stack; |
| } |
| @@ -465,6 +471,12 @@ unsigned int stack_depot_fetch(depot_sta |
| struct stack_record *stack; |
| |
| *entries = NULL; |
| + /* |
| + * Let KMSAN know *entries is initialized. This shall prevent false |
| + * positive reports if instrumented code accesses it. |
| + */ |
| + kmsan_unpoison_memory(entries, sizeof(*entries)); |
| + |
| if (!handle) |
| return 0; |
| |
| _ |