Skip to content

Commit b8abcba

Browse files
sergiocolladogregkh
authored andcommitted
Kunit to check the longest symbol length
commit c104c16 upstream. The longest length of a symbol (KSYM_NAME_LEN) was increased to 512 in the reference [1]. This patch adds kunit test suite to check the longest symbol length. These tests verify that the longest symbol length defined is supported. This test can also help other efforts for longer symbol length, like [2]. The test suite defines one symbol with the longest possible length. The first test verify that functions with names of the created symbol, can be called or not. The second test, verify that the symbols are created (or not) in the kernel symbol table. [1] https://lore.kernel.org/lkml/[email protected]/ [2] https://lore.kernel.org/lkml/[email protected]/ Link: https://lore.kernel.org/r/[email protected] Tested-by: Martin Rodriguez Reboredo <[email protected]> Reviewed-by: Shuah Khan <[email protected]> Reviewed-by: Rae Moar <[email protected]> Signed-off-by: Sergio González Collado <[email protected]> Link: Rust-for-Linux/linux#504 Reviewed-by: Rae Moar <[email protected]> Acked-by: David Gow <[email protected]> Signed-off-by: Shuah Khan <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c886784 commit b8abcba

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

arch/x86/tools/insn_decoder_test.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <assert.h>
1111
#include <unistd.h>
1212
#include <stdarg.h>
13+
#include <linux/kallsyms.h>
1314

1415
#define unlikely(cond) (cond)
1516

@@ -106,7 +107,7 @@ static void parse_args(int argc, char **argv)
106107
}
107108
}
108109

109-
#define BUFSIZE 256
110+
#define BUFSIZE (256 + KSYM_NAME_LEN)
110111

111112
int main(int argc, char **argv)
112113
{

lib/Kconfig.debug

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,6 +2807,15 @@ config FORTIFY_KUNIT_TEST
28072807
by the str*() and mem*() family of functions. For testing runtime
28082808
traps of FORTIFY_SOURCE, see LKDTM's "FORTIFY_*" tests.
28092809

2810+
config LONGEST_SYM_KUNIT_TEST
2811+
tristate "Test the longest symbol possible" if !KUNIT_ALL_TESTS
2812+
depends on KUNIT && KPROBES
2813+
default KUNIT_ALL_TESTS
2814+
help
2815+
Tests the longest symbol possible
2816+
2817+
If unsure, say N.
2818+
28102819
config HW_BREAKPOINT_KUNIT_TEST
28112820
bool "Test hw_breakpoint constraints accounting" if !KUNIT_ALL_TESTS
28122821
depends on HAVE_HW_BREAKPOINT

lib/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN)
389389
obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o
390390
obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
391391
obj-$(CONFIG_USERCOPY_KUNIT_TEST) += usercopy_kunit.o
392+
obj-$(CONFIG_LONGEST_SYM_KUNIT_TEST) += longest_symbol_kunit.o
393+
CFLAGS_longest_symbol_kunit.o += $(call cc-disable-warning, missing-prototypes)
392394

393395
obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
394396

lib/longest_symbol_kunit.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Test the longest symbol length. Execute with:
4+
* ./tools/testing/kunit/kunit.py run longest-symbol
5+
* --arch=x86_64 --kconfig_add CONFIG_KPROBES=y --kconfig_add CONFIG_MODULES=y
6+
* --kconfig_add CONFIG_RETPOLINE=n --kconfig_add CONFIG_CFI_CLANG=n
7+
* --kconfig_add CONFIG_MITIGATION_RETPOLINE=n
8+
*/
9+
10+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11+
12+
#include <kunit/test.h>
13+
#include <linux/stringify.h>
14+
#include <linux/kprobes.h>
15+
#include <linux/kallsyms.h>
16+
17+
#define DI(name) s##name##name
18+
#define DDI(name) DI(n##name##name)
19+
#define DDDI(name) DDI(n##name##name)
20+
#define DDDDI(name) DDDI(n##name##name)
21+
#define DDDDDI(name) DDDDI(n##name##name)
22+
23+
/*Generate a symbol whose name length is 511 */
24+
#define LONGEST_SYM_NAME DDDDDI(g1h2i3j4k5l6m7n)
25+
26+
#define RETURN_LONGEST_SYM 0xAAAAA
27+
28+
noinline int LONGEST_SYM_NAME(void);
29+
noinline int LONGEST_SYM_NAME(void)
30+
{
31+
return RETURN_LONGEST_SYM;
32+
}
33+
34+
_Static_assert(sizeof(__stringify(LONGEST_SYM_NAME)) == KSYM_NAME_LEN,
35+
"Incorrect symbol length found. Expected KSYM_NAME_LEN: "
36+
__stringify(KSYM_NAME_LEN) ", but found: "
37+
__stringify(sizeof(LONGEST_SYM_NAME)));
38+
39+
static void test_longest_symbol(struct kunit *test)
40+
{
41+
KUNIT_EXPECT_EQ(test, RETURN_LONGEST_SYM, LONGEST_SYM_NAME());
42+
};
43+
44+
static void test_longest_symbol_kallsyms(struct kunit *test)
45+
{
46+
unsigned long (*kallsyms_lookup_name)(const char *name);
47+
static int (*longest_sym)(void);
48+
49+
struct kprobe kp = {
50+
.symbol_name = "kallsyms_lookup_name",
51+
};
52+
53+
if (register_kprobe(&kp) < 0) {
54+
pr_info("%s: kprobe not registered", __func__);
55+
KUNIT_FAIL(test, "test_longest_symbol kallsyms: kprobe not registered\n");
56+
return;
57+
}
58+
59+
kunit_warn(test, "test_longest_symbol kallsyms: kprobe registered\n");
60+
kallsyms_lookup_name = (unsigned long (*)(const char *name))kp.addr;
61+
unregister_kprobe(&kp);
62+
63+
longest_sym =
64+
(void *) kallsyms_lookup_name(__stringify(LONGEST_SYM_NAME));
65+
KUNIT_EXPECT_EQ(test, RETURN_LONGEST_SYM, longest_sym());
66+
};
67+
68+
static struct kunit_case longest_symbol_test_cases[] = {
69+
KUNIT_CASE(test_longest_symbol),
70+
KUNIT_CASE(test_longest_symbol_kallsyms),
71+
{}
72+
};
73+
74+
static struct kunit_suite longest_symbol_test_suite = {
75+
.name = "longest-symbol",
76+
.test_cases = longest_symbol_test_cases,
77+
};
78+
kunit_test_suite(longest_symbol_test_suite);
79+
80+
MODULE_LICENSE("GPL");
81+
MODULE_DESCRIPTION("Test the longest symbol length");
82+
MODULE_AUTHOR("Sergio González Collado");

0 commit comments

Comments
 (0)