Commit 78a498c3 authored by Alexander Potapenko's avatar Alexander Potapenko Committed by Andrew Morton

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/89Signed-off-by: default avatarAlexander Potapenko <glider@google.com>
Reported-by: default avatarTamas 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: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 59c8a02e
...@@ -10,10 +10,13 @@ ...@@ -10,10 +10,13 @@
/* Even with __builtin_ the compiler may decide to use the out of line /* Even with __builtin_ the compiler may decide to use the out of line
function. */ function. */
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
#include <linux/kmsan_string.h>
#endif
#define __HAVE_ARCH_MEMCPY 1 #define __HAVE_ARCH_MEMCPY 1
#if defined(__SANITIZE_MEMORY__) #if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
#undef memcpy #undef memcpy
void *__msan_memcpy(void *dst, const void *src, size_t size);
#define memcpy __msan_memcpy #define memcpy __msan_memcpy
#else #else
extern void *memcpy(void *to, const void *from, size_t len); 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); ...@@ -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); extern void *__memcpy(void *to, const void *from, size_t len);
#define __HAVE_ARCH_MEMSET #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); extern void *__msan_memset(void *s, int c, size_t n);
#undef memset #undef memset
#define memset __msan_memset #define memset __msan_memset
...@@ -67,7 +70,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t n) ...@@ -67,7 +70,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t n)
} }
#define __HAVE_ARCH_MEMMOVE #define __HAVE_ARCH_MEMMOVE
#if defined(__SANITIZE_MEMORY__) #if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
#undef memmove #undef memmove
void *__msan_memmove(void *dest, const void *src, size_t len); void *__msan_memmove(void *dest, const void *src, size_t len);
#define memmove __msan_memmove #define memmove __msan_memmove
......
...@@ -43,11 +43,24 @@ extern __kernel_size_t __underlying_strlen(const char *p) __RENAME(strlen); ...@@ -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_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); extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy);
#else #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_memcpy __builtin_memcpy
#define __underlying_memmove __builtin_memmove #define __underlying_memmove __builtin_memmove
#define __underlying_memset __builtin_memset #define __underlying_memset __builtin_memset
#endif
#define __underlying_memchr __builtin_memchr
#define __underlying_memcmp __builtin_memcmp
#define __underlying_strcat __builtin_strcat #define __underlying_strcat __builtin_strcat
#define __underlying_strcpy __builtin_strcpy #define __underlying_strcpy __builtin_strcpy
#define __underlying_strlen __builtin_strlen #define __underlying_strlen __builtin_strlen
......
/* 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 @@ ...@@ -14,6 +14,7 @@
#include "kmsan.h" #include "kmsan.h"
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/kmsan_string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment