Skip to content

Commit 78a498c

Browse files
ramosian-gliderakpm00
authored andcommitted
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/[email protected] Link: google/kmsan#89 Signed-off-by: Alexander Potapenko <[email protected]> Reported-by: Tamas K Lengyel <[email protected]> Cc: Nathan Chancellor <[email protected]> Cc: Nick Desaulniers <[email protected]> Cc: Kees Cook <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 59c8a02 commit 78a498c

File tree

4 files changed

+44
-6
lines changed

4 files changed

+44
-6
lines changed

arch/x86/include/asm/string_64.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,21 @@
1010
/* Even with __builtin_ the compiler may decide to use the out of line
1111
function. */
1212

13+
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
14+
#include <linux/kmsan_string.h>
15+
#endif
16+
1317
#define __HAVE_ARCH_MEMCPY 1
14-
#if defined(__SANITIZE_MEMORY__)
18+
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
1519
#undef memcpy
16-
void *__msan_memcpy(void *dst, const void *src, size_t size);
1720
#define memcpy __msan_memcpy
1821
#else
1922
extern void *memcpy(void *to, const void *from, size_t len);
2023
#endif
2124
extern void *__memcpy(void *to, const void *from, size_t len);
2225

2326
#define __HAVE_ARCH_MEMSET
24-
#if defined(__SANITIZE_MEMORY__)
27+
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
2528
extern void *__msan_memset(void *s, int c, size_t n);
2629
#undef memset
2730
#define memset __msan_memset
@@ -67,7 +70,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t n)
6770
}
6871

6972
#define __HAVE_ARCH_MEMMOVE
70-
#if defined(__SANITIZE_MEMORY__)
73+
#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
7174
#undef memmove
7275
void *__msan_memmove(void *dest, const void *src, size_t len);
7376
#define memmove __msan_memmove

include/linux/fortify-string.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,24 @@ extern __kernel_size_t __underlying_strlen(const char *p) __RENAME(strlen);
4343
extern char *__underlying_strncat(char *p, const char *q, __kernel_size_t count) __RENAME(strncat);
4444
extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy);
4545
#else
46-
#define __underlying_memchr __builtin_memchr
47-
#define __underlying_memcmp __builtin_memcmp
46+
47+
#if defined(__SANITIZE_MEMORY__)
48+
/*
49+
* For KMSAN builds all memcpy/memset/memmove calls should be replaced by the
50+
* corresponding __msan_XXX functions.
51+
*/
52+
#include <linux/kmsan_string.h>
53+
#define __underlying_memcpy __msan_memcpy
54+
#define __underlying_memmove __msan_memmove
55+
#define __underlying_memset __msan_memset
56+
#else
4857
#define __underlying_memcpy __builtin_memcpy
4958
#define __underlying_memmove __builtin_memmove
5059
#define __underlying_memset __builtin_memset
60+
#endif
61+
62+
#define __underlying_memchr __builtin_memchr
63+
#define __underlying_memcmp __builtin_memcmp
5164
#define __underlying_strcat __builtin_strcat
5265
#define __underlying_strcpy __builtin_strcpy
5366
#define __underlying_strlen __builtin_strlen

include/linux/kmsan_string.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* KMSAN string functions API used in other headers.
4+
*
5+
* Copyright (C) 2022 Google LLC
6+
* Author: Alexander Potapenko <[email protected]>
7+
*
8+
*/
9+
#ifndef _LINUX_KMSAN_STRING_H
10+
#define _LINUX_KMSAN_STRING_H
11+
12+
/*
13+
* KMSAN overrides the default memcpy/memset/memmove implementations in the
14+
* kernel, which requires having __msan_XXX function prototypes in several other
15+
* headers. Keep them in one place instead of open-coding.
16+
*/
17+
void *__msan_memcpy(void *dst, const void *src, size_t size);
18+
void *__msan_memset(void *s, int c, size_t n);
19+
void *__msan_memmove(void *dest, const void *src, size_t len);
20+
21+
#endif /* _LINUX_KMSAN_STRING_H */

mm/kmsan/instrumentation.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "kmsan.h"
1616
#include <linux/gfp.h>
17+
#include <linux/kmsan_string.h>
1718
#include <linux/mm.h>
1819
#include <linux/uaccess.h>
1920

0 commit comments

Comments
 (0)