Skip to content

Commit 5835437

Browse files
Merge patch series "riscv: Improve KASAN coverage to fix unit tests"
Samuel Holland <[email protected]> says: This series fixes two areas where uninstrumented assembly routines caused gaps in KASAN coverage on RISC-V, which were caught by KUnit tests. The KASAN KUnit test suite passes after applying this series. This series fixes the following test failures: # kasan_strings: EXPECTATION FAILED at mm/kasan/kasan_test.c:1520 KASAN failure expected in "kasan_int_result = strcmp(ptr, "2")", but none occurred # kasan_strings: EXPECTATION FAILED at mm/kasan/kasan_test.c:1524 KASAN failure expected in "kasan_int_result = strlen(ptr)", but none occurred not ok 60 kasan_strings # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1531 KASAN failure expected in "set_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1533 KASAN failure expected in "clear_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1535 KASAN failure expected in "clear_bit_unlock(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1536 KASAN failure expected in "__clear_bit_unlock(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1537 KASAN failure expected in "change_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1543 KASAN failure expected in "test_and_set_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1545 KASAN failure expected in "test_and_set_bit_lock(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1546 KASAN failure expected in "test_and_clear_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1548 KASAN failure expected in "test_and_change_bit(nr, addr)", but none occurred not ok 61 kasan_bitops_generic Samuel Holland (2): riscv: Omit optimized string routines when using KASAN riscv: Enable bitops instrumentation arch/riscv/include/asm/bitops.h | 43 ++++++++++++++++++--------------- arch/riscv/include/asm/string.h | 2 ++ arch/riscv/kernel/riscv_ksyms.c | 3 --- arch/riscv/lib/Makefile | 2 ++ arch/riscv/lib/strcmp.S | 1 + arch/riscv/lib/strlen.S | 1 + arch/riscv/lib/strncmp.S | 1 + arch/riscv/purgatory/Makefile | 2 ++ 8 files changed, 32 insertions(+), 23 deletions(-) * b4-shazam-merge: riscv: Enable bitops instrumentation riscv: Omit optimized string routines when using KASAN Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
2 parents 21d98d6 + 7751491 commit 5835437

File tree

8 files changed

+32
-23
lines changed

8 files changed

+32
-23
lines changed

arch/riscv/include/asm/bitops.h

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,44 +222,44 @@ static __always_inline int variable_fls(unsigned int x)
222222
#define __NOT(x) (~(x))
223223

224224
/**
225-
* test_and_set_bit - Set a bit and return its old value
225+
* arch_test_and_set_bit - Set a bit and return its old value
226226
* @nr: Bit to set
227227
* @addr: Address to count from
228228
*
229229
* This operation may be reordered on other architectures than x86.
230230
*/
231-
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
231+
static inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
232232
{
233233
return __test_and_op_bit(or, __NOP, nr, addr);
234234
}
235235

236236
/**
237-
* test_and_clear_bit - Clear a bit and return its old value
237+
* arch_test_and_clear_bit - Clear a bit and return its old value
238238
* @nr: Bit to clear
239239
* @addr: Address to count from
240240
*
241241
* This operation can be reordered on other architectures other than x86.
242242
*/
243-
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
243+
static inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
244244
{
245245
return __test_and_op_bit(and, __NOT, nr, addr);
246246
}
247247

248248
/**
249-
* test_and_change_bit - Change a bit and return its old value
249+
* arch_test_and_change_bit - Change a bit and return its old value
250250
* @nr: Bit to change
251251
* @addr: Address to count from
252252
*
253253
* This operation is atomic and cannot be reordered.
254254
* It also implies a memory barrier.
255255
*/
256-
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
256+
static inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
257257
{
258258
return __test_and_op_bit(xor, __NOP, nr, addr);
259259
}
260260

261261
/**
262-
* set_bit - Atomically set a bit in memory
262+
* arch_set_bit - Atomically set a bit in memory
263263
* @nr: the bit to set
264264
* @addr: the address to start counting from
265265
*
@@ -270,68 +270,68 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
270270
* Note that @nr may be almost arbitrarily large; this function is not
271271
* restricted to acting on a single-word quantity.
272272
*/
273-
static inline void set_bit(int nr, volatile unsigned long *addr)
273+
static inline void arch_set_bit(int nr, volatile unsigned long *addr)
274274
{
275275
__op_bit(or, __NOP, nr, addr);
276276
}
277277

278278
/**
279-
* clear_bit - Clears a bit in memory
279+
* arch_clear_bit - Clears a bit in memory
280280
* @nr: Bit to clear
281281
* @addr: Address to start counting from
282282
*
283283
* Note: there are no guarantees that this function will not be reordered
284284
* on non x86 architectures, so if you are writing portable code,
285285
* make sure not to rely on its reordering guarantees.
286286
*/
287-
static inline void clear_bit(int nr, volatile unsigned long *addr)
287+
static inline void arch_clear_bit(int nr, volatile unsigned long *addr)
288288
{
289289
__op_bit(and, __NOT, nr, addr);
290290
}
291291

292292
/**
293-
* change_bit - Toggle a bit in memory
293+
* arch_change_bit - Toggle a bit in memory
294294
* @nr: Bit to change
295295
* @addr: Address to start counting from
296296
*
297297
* change_bit() may be reordered on other architectures than x86.
298298
* Note that @nr may be almost arbitrarily large; this function is not
299299
* restricted to acting on a single-word quantity.
300300
*/
301-
static inline void change_bit(int nr, volatile unsigned long *addr)
301+
static inline void arch_change_bit(int nr, volatile unsigned long *addr)
302302
{
303303
__op_bit(xor, __NOP, nr, addr);
304304
}
305305

306306
/**
307-
* test_and_set_bit_lock - Set a bit and return its old value, for lock
307+
* arch_test_and_set_bit_lock - Set a bit and return its old value, for lock
308308
* @nr: Bit to set
309309
* @addr: Address to count from
310310
*
311311
* This operation is atomic and provides acquire barrier semantics.
312312
* It can be used to implement bit locks.
313313
*/
314-
static inline int test_and_set_bit_lock(
314+
static inline int arch_test_and_set_bit_lock(
315315
unsigned long nr, volatile unsigned long *addr)
316316
{
317317
return __test_and_op_bit_ord(or, __NOP, nr, addr, .aq);
318318
}
319319

320320
/**
321-
* clear_bit_unlock - Clear a bit in memory, for unlock
321+
* arch_clear_bit_unlock - Clear a bit in memory, for unlock
322322
* @nr: the bit to set
323323
* @addr: the address to start counting from
324324
*
325325
* This operation is atomic and provides release barrier semantics.
326326
*/
327-
static inline void clear_bit_unlock(
327+
static inline void arch_clear_bit_unlock(
328328
unsigned long nr, volatile unsigned long *addr)
329329
{
330330
__op_bit_ord(and, __NOT, nr, addr, .rl);
331331
}
332332

333333
/**
334-
* __clear_bit_unlock - Clear a bit in memory, for unlock
334+
* arch___clear_bit_unlock - Clear a bit in memory, for unlock
335335
* @nr: the bit to set
336336
* @addr: the address to start counting from
337337
*
@@ -345,13 +345,13 @@ static inline void clear_bit_unlock(
345345
* non-atomic property here: it's a lot more instructions and we still have to
346346
* provide release semantics anyway.
347347
*/
348-
static inline void __clear_bit_unlock(
348+
static inline void arch___clear_bit_unlock(
349349
unsigned long nr, volatile unsigned long *addr)
350350
{
351-
clear_bit_unlock(nr, addr);
351+
arch_clear_bit_unlock(nr, addr);
352352
}
353353

354-
static inline bool xor_unlock_is_negative_byte(unsigned long mask,
354+
static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
355355
volatile unsigned long *addr)
356356
{
357357
unsigned long res;
@@ -369,6 +369,9 @@ static inline bool xor_unlock_is_negative_byte(unsigned long mask,
369369
#undef __NOT
370370
#undef __AMO
371371

372+
#include <asm-generic/bitops/instrumented-atomic.h>
373+
#include <asm-generic/bitops/instrumented-lock.h>
374+
372375
#include <asm-generic/bitops/non-atomic.h>
373376
#include <asm-generic/bitops/le.h>
374377
#include <asm-generic/bitops/ext2-atomic.h>

arch/riscv/include/asm/string.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern asmlinkage void *__memcpy(void *, const void *, size_t);
1919
extern asmlinkage void *memmove(void *, const void *, size_t);
2020
extern asmlinkage void *__memmove(void *, const void *, size_t);
2121

22+
#if !(defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS))
2223
#define __HAVE_ARCH_STRCMP
2324
extern asmlinkage int strcmp(const char *cs, const char *ct);
2425

@@ -27,6 +28,7 @@ extern asmlinkage __kernel_size_t strlen(const char *);
2728

2829
#define __HAVE_ARCH_STRNCMP
2930
extern asmlinkage int strncmp(const char *cs, const char *ct, size_t count);
31+
#endif
3032

3133
/* For those files which don't want to check by kasan. */
3234
#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)

arch/riscv/kernel/riscv_ksyms.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
EXPORT_SYMBOL(memset);
1313
EXPORT_SYMBOL(memcpy);
1414
EXPORT_SYMBOL(memmove);
15-
EXPORT_SYMBOL(strcmp);
16-
EXPORT_SYMBOL(strlen);
17-
EXPORT_SYMBOL(strncmp);
1815
EXPORT_SYMBOL(__memset);
1916
EXPORT_SYMBOL(__memcpy);
2017
EXPORT_SYMBOL(__memmove);

arch/riscv/lib/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ lib-y += delay.o
33
lib-y += memcpy.o
44
lib-y += memset.o
55
lib-y += memmove.o
6+
ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
67
lib-y += strcmp.o
78
lib-y += strlen.o
89
lib-y += strncmp.o
10+
endif
911
lib-y += csum.o
1012
ifeq ($(CONFIG_MMU), y)
1113
lib-$(CONFIG_RISCV_ISA_V) += uaccess_vector.o

arch/riscv/lib/strcmp.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,4 @@ strcmp_zbb:
121121
#endif
122122
SYM_FUNC_END(strcmp)
123123
SYM_FUNC_ALIAS(__pi_strcmp, strcmp)
124+
EXPORT_SYMBOL(strcmp)

arch/riscv/lib/strlen.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,4 @@ strlen_zbb:
131131
#endif
132132
SYM_FUNC_END(strlen)
133133
SYM_FUNC_ALIAS(__pi_strlen, strlen)
134+
EXPORT_SYMBOL(strlen)

arch/riscv/lib/strncmp.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,4 @@ strncmp_zbb:
137137
#endif
138138
SYM_FUNC_END(strncmp)
139139
SYM_FUNC_ALIAS(__pi_strncmp, strncmp)
140+
EXPORT_SYMBOL(strncmp)

arch/riscv/purgatory/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
4+
ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
45
purgatory-y += strcmp.o strlen.o strncmp.o
6+
endif
57

68
targets += $(purgatory-y)
79
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))

0 commit comments

Comments
 (0)