x86: fortify: kmsan: fix KMSAN fortify builds
Ensure that KMSAN builds replace memset/memcpy/memmove calls with the respective __msan_XXX functions, and that none of the macros are redefined twice. This should allow building kernel with both CONFIG_KMSAN and CONFIG_FORTIFY_SOURCE. Link: https://lkml.kernel.org/r/20221024212144.2852069-5-glider@google.com Link: https://github.com/google/kmsan/issues/89 Signed-off-by: Alexander Potapenko <glider@google.com> Reported-by: Tamas K Lengyel <tamas.lengyel@zentific.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Kees Cook <keescook@chromium.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
59c8a02e24
commit
78a498c3a2
@ -10,10 +10,13 @@
|
||||
/* Even with __builtin_ the compiler may decide to use the out of line
|
||||
function. */
|
||||
|
||||
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
|
||||
#include <linux/kmsan_string.h>
|
||||
#endif
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY 1
|
||||
#if defined(__SANITIZE_MEMORY__)
|
||||
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
|
||||
#undef memcpy
|
||||
void *__msan_memcpy(void *dst, const void *src, size_t size);
|
||||
#define memcpy __msan_memcpy
|
||||
#else
|
||||
extern void *memcpy(void *to, const void *from, size_t len);
|
||||
@ -21,7 +24,7 @@ extern void *memcpy(void *to, const void *from, size_t len);
|
||||
extern void *__memcpy(void *to, const void *from, size_t len);
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
#if defined(__SANITIZE_MEMORY__)
|
||||
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
|
||||
extern void *__msan_memset(void *s, int c, size_t n);
|
||||
#undef memset
|
||||
#define memset __msan_memset
|
||||
@ -67,7 +70,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t n)
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
#if defined(__SANITIZE_MEMORY__)
|
||||
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
|
||||
#undef memmove
|
||||
void *__msan_memmove(void *dest, const void *src, size_t len);
|
||||
#define memmove __msan_memmove
|
||||
|
@ -43,11 +43,24 @@ extern __kernel_size_t __underlying_strlen(const char *p) __RENAME(strlen);
|
||||
extern char *__underlying_strncat(char *p, const char *q, __kernel_size_t count) __RENAME(strncat);
|
||||
extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy);
|
||||
#else
|
||||
#define __underlying_memchr __builtin_memchr
|
||||
#define __underlying_memcmp __builtin_memcmp
|
||||
|
||||
#if defined(__SANITIZE_MEMORY__)
|
||||
/*
|
||||
* For KMSAN builds all memcpy/memset/memmove calls should be replaced by the
|
||||
* corresponding __msan_XXX functions.
|
||||
*/
|
||||
#include <linux/kmsan_string.h>
|
||||
#define __underlying_memcpy __msan_memcpy
|
||||
#define __underlying_memmove __msan_memmove
|
||||
#define __underlying_memset __msan_memset
|
||||
#else
|
||||
#define __underlying_memcpy __builtin_memcpy
|
||||
#define __underlying_memmove __builtin_memmove
|
||||
#define __underlying_memset __builtin_memset
|
||||
#endif
|
||||
|
||||
#define __underlying_memchr __builtin_memchr
|
||||
#define __underlying_memcmp __builtin_memcmp
|
||||
#define __underlying_strcat __builtin_strcat
|
||||
#define __underlying_strcpy __builtin_strcpy
|
||||
#define __underlying_strlen __builtin_strlen
|
||||
|
21
include/linux/kmsan_string.h
Normal file
21
include/linux/kmsan_string.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* KMSAN string functions API used in other headers.
|
||||
*
|
||||
* Copyright (C) 2022 Google LLC
|
||||
* Author: Alexander Potapenko <glider@google.com>
|
||||
*
|
||||
*/
|
||||
#ifndef _LINUX_KMSAN_STRING_H
|
||||
#define _LINUX_KMSAN_STRING_H
|
||||
|
||||
/*
|
||||
* KMSAN overrides the default memcpy/memset/memmove implementations in the
|
||||
* kernel, which requires having __msan_XXX function prototypes in several other
|
||||
* headers. Keep them in one place instead of open-coding.
|
||||
*/
|
||||
void *__msan_memcpy(void *dst, const void *src, size_t size);
|
||||
void *__msan_memset(void *s, int c, size_t n);
|
||||
void *__msan_memmove(void *dest, const void *src, size_t len);
|
||||
|
||||
#endif /* _LINUX_KMSAN_STRING_H */
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "kmsan.h"
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/kmsan_string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user