Skip to content

Commit fe8e353

Browse files
keesgregkh
authored andcommitted
lkdtm/fortify: Consolidate FORTIFY_SOURCE tests
The FORTIFY_SOURCE tests were split between bugs.c and fortify.c. Move tests into fortify.c, standardize their naming, add CONFIG hints, and add them to the lkdtm selftests. Cc: Arnd Bergmann <[email protected]> Signed-off-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c75be56 commit fe8e353

File tree

5 files changed

+59
-54
lines changed

5 files changed

+59
-54
lines changed

drivers/misc/lkdtm/bugs.c

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -507,53 +507,3 @@ noinline void lkdtm_CORRUPT_PAC(void)
507507
pr_err("XFAIL: this test is arm64-only\n");
508508
#endif
509509
}
510-
511-
void lkdtm_FORTIFY_OBJECT(void)
512-
{
513-
struct target {
514-
char a[10];
515-
} target[2] = {};
516-
int result;
517-
518-
/*
519-
* Using volatile prevents the compiler from determining the value of
520-
* 'size' at compile time. Without that, we would get a compile error
521-
* rather than a runtime error.
522-
*/
523-
volatile int size = 11;
524-
525-
pr_info("trying to read past the end of a struct\n");
526-
527-
result = memcmp(&target[0], &target[1], size);
528-
529-
/* Print result to prevent the code from being eliminated */
530-
pr_err("FAIL: fortify did not catch an object overread!\n"
531-
"\"%d\" was the memcmp result.\n", result);
532-
}
533-
534-
void lkdtm_FORTIFY_SUBOBJECT(void)
535-
{
536-
struct target {
537-
char a[10];
538-
char b[10];
539-
} target;
540-
char *src;
541-
542-
src = kmalloc(20, GFP_KERNEL);
543-
strscpy(src, "over ten bytes", 20);
544-
545-
pr_info("trying to strcpy past the end of a member of a struct\n");
546-
547-
/*
548-
* strncpy(target.a, src, 20); will hit a compile error because the
549-
* compiler knows at build time that target.a < 20 bytes. Use strcpy()
550-
* to force a runtime error.
551-
*/
552-
strcpy(target.a, src);
553-
554-
/* Use target.a to prevent the code from being eliminated */
555-
pr_err("FAIL: fortify did not catch an sub-object overrun!\n"
556-
"\"%s\" was copied.\n", target.a);
557-
558-
kfree(src);
559-
}

drivers/misc/lkdtm/core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ static const struct crashtype crashtypes[] = {
118118
CRASHTYPE(UNSET_SMEP),
119119
CRASHTYPE(CORRUPT_PAC),
120120
CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
121-
CRASHTYPE(FORTIFY_OBJECT),
122-
CRASHTYPE(FORTIFY_SUBOBJECT),
123121
CRASHTYPE(SLAB_LINEAR_OVERFLOW),
124122
CRASHTYPE(VMALLOC_LINEAR_OVERFLOW),
125123
CRASHTYPE(WRITE_AFTER_FREE),
@@ -179,6 +177,8 @@ static const struct crashtype crashtypes[] = {
179177
CRASHTYPE(USERCOPY_KERNEL),
180178
CRASHTYPE(STACKLEAK_ERASING),
181179
CRASHTYPE(CFI_FORWARD_PROTO),
180+
CRASHTYPE(FORTIFIED_OBJECT),
181+
CRASHTYPE(FORTIFIED_SUBOBJECT),
182182
CRASHTYPE(FORTIFIED_STRSCPY),
183183
CRASHTYPE(DOUBLE_FAULT),
184184
#ifdef CONFIG_PPC_BOOK3S_64

drivers/misc/lkdtm/fortify.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,59 @@
88
#include <linux/string.h>
99
#include <linux/slab.h>
1010

11+
static volatile int fortify_scratch_space;
12+
13+
void lkdtm_FORTIFIED_OBJECT(void)
14+
{
15+
struct target {
16+
char a[10];
17+
} target[2] = {};
18+
/*
19+
* Using volatile prevents the compiler from determining the value of
20+
* 'size' at compile time. Without that, we would get a compile error
21+
* rather than a runtime error.
22+
*/
23+
volatile int size = 11;
24+
25+
pr_info("trying to read past the end of a struct\n");
26+
27+
/* Store result to global to prevent the code from being eliminated */
28+
fortify_scratch_space = memcmp(&target[0], &target[1], size);
29+
30+
pr_err("FAIL: fortify did not block an object overread!\n");
31+
pr_expected_config(CONFIG_FORTIFY_SOURCE);
32+
}
33+
34+
void lkdtm_FORTIFIED_SUBOBJECT(void)
35+
{
36+
struct target {
37+
char a[10];
38+
char b[10];
39+
} target;
40+
volatile int size = 20;
41+
char *src;
42+
43+
src = kmalloc(size, GFP_KERNEL);
44+
strscpy(src, "over ten bytes", size);
45+
size = strlen(src) + 1;
46+
47+
pr_info("trying to strcpy past the end of a member of a struct\n");
48+
49+
/*
50+
* memcpy(target.a, src, 20); will hit a compile error because the
51+
* compiler knows at build time that target.a < 20 bytes. Use a
52+
* volatile to force a runtime error.
53+
*/
54+
memcpy(target.a, src, size);
55+
56+
/* Store result to global to prevent the code from being eliminated */
57+
fortify_scratch_space = target.a[3];
58+
59+
pr_err("FAIL: fortify did not block an sub-object overrun!\n");
60+
pr_expected_config(CONFIG_FORTIFY_SOURCE);
61+
62+
kfree(src);
63+
}
1164

1265
/*
1366
* Calls fortified strscpy to test that it returns the same result as vanilla

drivers/misc/lkdtm/lkdtm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ void lkdtm_STACK_GUARD_PAGE_TRAILING(void);
7474
void lkdtm_UNSET_SMEP(void);
7575
void lkdtm_DOUBLE_FAULT(void);
7676
void lkdtm_CORRUPT_PAC(void);
77-
void lkdtm_FORTIFY_OBJECT(void);
78-
void lkdtm_FORTIFY_SUBOBJECT(void);
7977

8078
/* heap.c */
8179
void __init lkdtm_heap_init(void);
@@ -150,6 +148,8 @@ void lkdtm_STACKLEAK_ERASING(void);
150148
void lkdtm_CFI_FORWARD_PROTO(void);
151149

152150
/* fortify.c */
151+
void lkdtm_FORTIFIED_OBJECT(void);
152+
void lkdtm_FORTIFIED_SUBOBJECT(void);
153153
void lkdtm_FORTIFIED_STRSCPY(void);
154154

155155
/* powerpc.c */

tools/testing/selftests/lkdtm/tests.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,6 @@ USERCOPY_KERNEL
7373
STACKLEAK_ERASING OK: the rest of the thread stack is properly erased
7474
CFI_FORWARD_PROTO
7575
FORTIFIED_STRSCPY
76+
FORTIFIED_OBJECT
77+
FORTIFIED_SUBOBJECT
7678
PPC_SLB_MULTIHIT Recovered

0 commit comments

Comments
 (0)