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 27/46] kmsan: instrumentation.h: add instrumentation_begin_with_regs()
    From
    When calling KMSAN-instrumented functions from non-instrumented
    functions, function parameters may not be initialized properly, leading
    to false positive reports. In particular, this happens all the time when
    calling interrupt handlers from `noinstr` IDT entries.

    We introduce instrumentation_begin_with_regs(), which calls
    instrumentation_begin() and notifies KMSAN about the beginning of the
    potentially instrumented region by calling
    kmsan_instrumentation_begin(), which:
    - wipes the current KMSAN state at the beginning of the region, ensuring
    that the first call of an instrumented function receives initialized
    parameters (this is a pretty good approximation of having all other
    instrumented functions receive initialized parameters);
    - unpoisons the `struct pt_regs` set up by the non-instrumented assembly
    code.

    Signed-off-by: Alexander Potapenko <glider@google.com>
    ---
    Link: https://linux-review.googlesource.com/id/I0f5e3372e00bd5fe25ddbf286f7260aae9011858
    ---
    include/linux/instrumentation.h | 6 ++++++
    include/linux/kmsan.h | 11 +++++++++++
    mm/kmsan/hooks.c | 16 ++++++++++++++++
    3 files changed, 33 insertions(+)

    diff --git a/include/linux/instrumentation.h b/include/linux/instrumentation.h
    index 24359b4a96053..3bbce9d556381 100644
    --- a/include/linux/instrumentation.h
    +++ b/include/linux/instrumentation.h
    @@ -15,6 +15,11 @@
    })
    #define instrumentation_begin() __instrumentation_begin(__COUNTER__)

    +#define instrumentation_begin_with_regs(regs) do { \
    + __instrumentation_begin(__COUNTER__); \
    + kmsan_instrumentation_begin(regs); \
    +} while (0)
    +
    /*
    * Because instrumentation_{begin,end}() can nest, objtool validation considers
    * _begin() a +1 and _end() a -1 and computes a sum over the instructions.
    @@ -55,6 +60,7 @@
    #define instrumentation_end() __instrumentation_end(__COUNTER__)
    #else
    # define instrumentation_begin() do { } while(0)
    +# define instrumentation_begin_with_regs(regs) kmsan_instrumentation_begin(regs)
    # define instrumentation_end() do { } while(0)
    #endif

    diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
    index 55f976b721566..209a5a2192e22 100644
    --- a/include/linux/kmsan.h
    +++ b/include/linux/kmsan.h
    @@ -247,6 +247,13 @@ void kmsan_handle_dma_sg(struct scatterlist *sg, int nents,
    */
    void kmsan_handle_urb(const struct urb *urb, bool is_out);

    +/**
    + * kmsan_instrumentation_begin() - handle instrumentation_begin().
    + * @regs: pointer to struct pt_regs that non-instrumented code passes to
    + * instrumented code.
    + */
    +void kmsan_instrumentation_begin(struct pt_regs *regs);
    +
    #else

    static inline void kmsan_init_shadow(void)
    @@ -343,6 +350,10 @@ static inline void kmsan_handle_urb(const struct urb *urb, bool is_out)
    {
    }

    +static inline void kmsan_instrumentation_begin(struct pt_regs *regs)
    +{
    +}
    +
    #endif

    #endif /* _LINUX_KMSAN_H */
    diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
    index 9aecbf2825837..c20d105c143c1 100644
    --- a/mm/kmsan/hooks.c
    +++ b/mm/kmsan/hooks.c
    @@ -366,3 +366,19 @@ void kmsan_check_memory(const void *addr, size_t size)
    REASON_ANY);
    }
    EXPORT_SYMBOL(kmsan_check_memory);
    +
    +void kmsan_instrumentation_begin(struct pt_regs *regs)
    +{
    + struct kmsan_context_state *state = &kmsan_get_context()->cstate;
    +
    + if (state)
    + __memset(state, 0, sizeof(struct kmsan_context_state));
    + if (!kmsan_enabled || !regs)
    + return;
    + /*
    + * @regs may reside in cpu_entry_area, for which KMSAN does not allocate
    + * metadata. Do not force an error in that case.
    + */
    + kmsan_internal_unpoison_memory(regs, sizeof(*regs), /*checked*/ false);
    +}
    +EXPORT_SYMBOL(kmsan_instrumentation_begin);
    --
    2.36.0.rc2.479.g8af0fa9b8e-goog
    \
     
     \ /
      Last update: 2022-04-26 18:49    [W:4.149 / U:0.220 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site