Skip to content

Commit

Permalink
mm: kmsan: implement kmsan_memmove()
Browse files Browse the repository at this point in the history
Provide a hook that can be used by custom memcpy implementations to tell
KMSAN that the metadata needs to be copied.  Without that, false positive
reports are possible in the cases where KMSAN fails to intercept memory
initialization.

Link: https://lore.kernel.org/all/3b7dbd88-0861-4638-b2d2-911c97a4cadf@I-love.SAKURA.ne.jp/
Link: https://lkml.kernel.org/r/20240320101851.2589698-1-glider@google.com
Signed-off-by: Alexander Potapenko <glider@google.com>
Suggested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reviewed-by: Marco Elver <elver@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
  • Loading branch information
ramosian-glider authored and akpm00 committed Apr 26, 2024
1 parent 212f863 commit 3429055
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
15 changes: 15 additions & 0 deletions include/linux/kmsan-checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ void kmsan_check_memory(const void *address, size_t size);
void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
size_t left);

/**
* kmsan_memmove() - Notify KMSAN about a data copy within kernel.
* @to: destination address in the kernel.
* @from: source address in the kernel.
* @size: number of bytes to copy.
*
* Invoked after non-instrumented version (e.g. implemented using assembly
* code) of memmove()/memcpy() is called, in order to copy KMSAN's metadata.
*/
void kmsan_memmove(void *to, const void *from, size_t to_copy);

#else

static inline void kmsan_poison_memory(const void *address, size_t size,
Expand All @@ -78,6 +89,10 @@ static inline void kmsan_copy_to_user(void __user *to, const void *from,
{
}

static inline void kmsan_memmove(void *to, const void *from, size_t to_copy)
{
}

#endif

#endif /* _LINUX_KMSAN_CHECKS_H */
11 changes: 11 additions & 0 deletions mm/kmsan/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,17 @@ void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
}
EXPORT_SYMBOL(kmsan_copy_to_user);

void kmsan_memmove(void *to, const void *from, size_t size)
{
if (!kmsan_enabled || kmsan_in_runtime())
return;

kmsan_enter_runtime();
kmsan_internal_memmove_metadata(to, (void *)from, size);
kmsan_leave_runtime();
}
EXPORT_SYMBOL(kmsan_memmove);

/* Helper function to check an URB. */
void kmsan_handle_urb(const struct urb *urb, bool is_out)
{
Expand Down

0 comments on commit 3429055

Please sign in to comment.