lkml.org 
[lkml]   [2022]   [Apr]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v3 18/46] kmsan: handle task creation and exiting
    From
    Tell KMSAN that a new task is created, so the tool creates a backing
    metadata structure for that task.

    Signed-off-by: Alexander Potapenko <glider@google.com>
    ---
    v2:
    -- move implementation of kmsan_task_create() and kmsan_task_exit() here

    Link: https://linux-review.googlesource.com/id/I0f41c3a1c7d66f7e14aabcfdfc7c69addb945805
    ---
    include/linux/kmsan.h | 17 +++++++++++++++++
    kernel/exit.c | 2 ++
    kernel/fork.c | 2 ++
    mm/kmsan/core.c | 10 ++++++++++
    mm/kmsan/hooks.c | 19 +++++++++++++++++++
    mm/kmsan/kmsan.h | 2 ++
    6 files changed, 52 insertions(+)

    diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
    index ed3630068e2ef..dca42e0e91991 100644
    --- a/include/linux/kmsan.h
    +++ b/include/linux/kmsan.h
    @@ -17,6 +17,7 @@

    struct page;
    struct kmem_cache;
    +struct task_struct;

    #ifdef CONFIG_KMSAN

    @@ -43,6 +44,14 @@ struct kmsan_ctx {
    bool allow_reporting;
    };

    +void kmsan_task_create(struct task_struct *task);
    +
    +/**
    + * kmsan_task_exit() - Notify KMSAN that a task has exited.
    + * @task: task about to finish.
    + */
    +void kmsan_task_exit(struct task_struct *task);
    +
    /**
    * kmsan_alloc_page() - Notify KMSAN about an alloc_pages() call.
    * @page: struct page pointer returned by alloc_pages().
    @@ -164,6 +173,14 @@ void kmsan_iounmap_page_range(unsigned long start, unsigned long end);

    #else

    +static inline void kmsan_task_create(struct task_struct *task)
    +{
    +}
    +
    +static inline void kmsan_task_exit(struct task_struct *task)
    +{
    +}
    +
    static inline int kmsan_alloc_page(struct page *page, unsigned int order,
    gfp_t flags)
    {
    diff --git a/kernel/exit.c b/kernel/exit.c
    index f072959fcab7f..1784b7a741ddd 100644
    --- a/kernel/exit.c
    +++ b/kernel/exit.c
    @@ -60,6 +60,7 @@
    #include <linux/writeback.h>
    #include <linux/shm.h>
    #include <linux/kcov.h>
    +#include <linux/kmsan.h>
    #include <linux/random.h>
    #include <linux/rcuwait.h>
    #include <linux/compat.h>
    @@ -741,6 +742,7 @@ void __noreturn do_exit(long code)
    WARN_ON(tsk->plug);

    kcov_task_exit(tsk);
    + kmsan_task_exit(tsk);

    coredump_task_exit(tsk);
    ptrace_event(PTRACE_EVENT_EXIT, code);
    diff --git a/kernel/fork.c b/kernel/fork.c
    index 9796897560ab1..a6178bd28c409 100644
    --- a/kernel/fork.c
    +++ b/kernel/fork.c
    @@ -37,6 +37,7 @@
    #include <linux/fdtable.h>
    #include <linux/iocontext.h>
    #include <linux/key.h>
    +#include <linux/kmsan.h>
    #include <linux/binfmts.h>
    #include <linux/mman.h>
    #include <linux/mmu_notifier.h>
    @@ -1027,6 +1028,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
    tsk->worker_private = NULL;

    kcov_task_init(tsk);
    + kmsan_task_create(tsk);
    kmap_local_fork(tsk);

    #ifdef CONFIG_FAULT_INJECTION
    diff --git a/mm/kmsan/core.c b/mm/kmsan/core.c
    index 933d864d9d467..4b405abbb6c03 100644
    --- a/mm/kmsan/core.c
    +++ b/mm/kmsan/core.c
    @@ -44,6 +44,16 @@ bool kmsan_enabled __read_mostly;
    */
    DEFINE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx);

    +void kmsan_internal_task_create(struct task_struct *task)
    +{
    + struct kmsan_ctx *ctx = &task->kmsan_ctx;
    +
    + __memset(ctx, 0, sizeof(struct kmsan_ctx));
    + ctx->allow_reporting = true;
    + kmsan_internal_unpoison_memory(current_thread_info(),
    + sizeof(struct thread_info), false);
    +}
    +
    void kmsan_internal_poison_memory(void *address, size_t size, gfp_t flags,
    unsigned int poison_flags)
    {
    diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
    index 052e17b7a717d..43a529569053d 100644
    --- a/mm/kmsan/hooks.c
    +++ b/mm/kmsan/hooks.c
    @@ -26,6 +26,25 @@
    * skipping effects of functions like memset() inside instrumented code.
    */

    +void kmsan_task_create(struct task_struct *task)
    +{
    + kmsan_enter_runtime();
    + kmsan_internal_task_create(task);
    + kmsan_leave_runtime();
    +}
    +EXPORT_SYMBOL(kmsan_task_create);
    +
    +void kmsan_task_exit(struct task_struct *task)
    +{
    + struct kmsan_ctx *ctx = &task->kmsan_ctx;
    +
    + if (!kmsan_enabled || kmsan_in_runtime())
    + return;
    +
    + ctx->allow_reporting = false;
    +}
    +EXPORT_SYMBOL(kmsan_task_exit);
    +
    void kmsan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags)
    {
    if (unlikely(object == NULL))
    diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h
    index bfe38789950a6..a1b5900ffd97b 100644
    --- a/mm/kmsan/kmsan.h
    +++ b/mm/kmsan/kmsan.h
    @@ -172,6 +172,8 @@ void kmsan_internal_set_shadow_origin(void *address, size_t size, int b,
    u32 origin, bool checked);
    depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id);

    +void kmsan_internal_task_create(struct task_struct *task);
    +
    bool kmsan_metadata_is_contiguous(void *addr, size_t size);
    void kmsan_internal_check_memory(void *addr, size_t size, const void *user_addr,
    int reason);
    --
    2.36.0.rc2.479.g8af0fa9b8e-goog
    \
     
     \ /
      Last update: 2022-04-26 18:48    [W:3.506 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site