Skip to content

Commit f55aef7

Browse files
committed
lib/tests: randstruct: Add deep function pointer layout test
The recent fix in commit c2ea09b ("randstruct: gcc-plugin: Remove bogus void member") has fixed another issue: it was not always detecting composite structures made only of function pointers and structures of function pointers. Add a test for this case, and break out the layout tests since this issue is actually a problem for Clang as well[1]. Link: llvm/llvm-project#138355 [1] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Kees Cook <[email protected]>
1 parent b370f7e commit f55aef7

File tree

1 file changed

+65
-14
lines changed

1 file changed

+65
-14
lines changed

lib/tests/randstruct_kunit.c

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ struct randstruct_funcs_untouched {
5656
struct randstruct_funcs_shuffled {
5757
DO_MANY_MEMBERS(func_member)
5858
};
59-
#undef func_member
6059

6160
#define func_body(x, ignored) \
6261
static noinline size_t func_##x(int arg) \
@@ -103,9 +102,16 @@ struct contains_randstruct_shuffled {
103102
int after;
104103
};
105104

106-
static void randstruct_layout(struct kunit *test)
107-
{
108-
int mismatches;
105+
struct contains_func_untouched {
106+
struct randstruct_funcs_shuffled inner;
107+
DO_MANY_MEMBERS(func_member)
108+
} __no_randomize_layout;
109+
110+
struct contains_func_shuffled {
111+
struct randstruct_funcs_shuffled inner;
112+
DO_MANY_MEMBERS(func_member)
113+
};
114+
#undef func_member
109115

110116
#define check_mismatch(x, untouched, shuffled) \
111117
if (offsetof(untouched, x) != offsetof(shuffled, x)) \
@@ -114,24 +120,66 @@ static void randstruct_layout(struct kunit *test)
114120
offsetof(shuffled, x), \
115121
offsetof(untouched, x)); \
116122

117-
#define check_pair(outcome, untouched, shuffled) \
123+
#define check_pair(outcome, untouched, shuffled, checker...) \
118124
mismatches = 0; \
119-
DO_MANY_MEMBERS(check_mismatch, untouched, shuffled) \
125+
DO_MANY_MEMBERS(checker, untouched, shuffled) \
120126
kunit_info(test, "Differing " #untouched " vs " #shuffled " member positions: %d\n", \
121127
mismatches); \
122128
KUNIT_##outcome##_MSG(test, mismatches, 0, \
123129
#untouched " vs " #shuffled " layouts: unlucky or broken?\n");
124130

125-
check_pair(EXPECT_EQ, struct randstruct_untouched, struct randstruct_untouched)
126-
check_pair(EXPECT_GT, struct randstruct_untouched, struct randstruct_shuffled)
127-
check_pair(EXPECT_GT, struct randstruct_untouched, struct randstruct_funcs_shuffled)
128-
check_pair(EXPECT_GT, struct randstruct_funcs_untouched, struct randstruct_funcs_shuffled)
129-
check_pair(EXPECT_GT, struct randstruct_mixed_untouched, struct randstruct_mixed_shuffled)
130-
#undef check_pair
131+
static void randstruct_layout_same(struct kunit *test)
132+
{
133+
int mismatches;
131134

132-
#undef check_mismatch
135+
check_pair(EXPECT_EQ, struct randstruct_untouched, struct randstruct_untouched,
136+
check_mismatch)
137+
check_pair(EXPECT_GT, struct randstruct_untouched, struct randstruct_shuffled,
138+
check_mismatch)
139+
}
140+
141+
static void randstruct_layout_mixed(struct kunit *test)
142+
{
143+
int mismatches;
144+
145+
check_pair(EXPECT_EQ, struct randstruct_mixed_untouched, struct randstruct_mixed_untouched,
146+
check_mismatch)
147+
check_pair(EXPECT_GT, struct randstruct_mixed_untouched, struct randstruct_mixed_shuffled,
148+
check_mismatch)
133149
}
134150

151+
static void randstruct_layout_fptr(struct kunit *test)
152+
{
153+
int mismatches;
154+
155+
check_pair(EXPECT_EQ, struct randstruct_untouched, struct randstruct_untouched,
156+
check_mismatch)
157+
check_pair(EXPECT_GT, struct randstruct_untouched, struct randstruct_funcs_shuffled,
158+
check_mismatch)
159+
check_pair(EXPECT_GT, struct randstruct_funcs_untouched, struct randstruct_funcs_shuffled,
160+
check_mismatch)
161+
}
162+
163+
#define check_mismatch_prefixed(x, prefix, untouched, shuffled) \
164+
check_mismatch(prefix.x, untouched, shuffled)
165+
166+
static void randstruct_layout_fptr_deep(struct kunit *test)
167+
{
168+
int mismatches;
169+
170+
if (IS_ENABLED(CONFIG_CC_IS_CLANG))
171+
kunit_skip(test, "Clang randstruct misses inner functions: https://github.com/llvm/llvm-project/issues/138355");
172+
173+
check_pair(EXPECT_EQ, struct contains_func_untouched, struct contains_func_untouched,
174+
check_mismatch_prefixed, inner)
175+
176+
check_pair(EXPECT_GT, struct contains_func_untouched, struct contains_func_shuffled,
177+
check_mismatch_prefixed, inner)
178+
}
179+
180+
#undef check_pair
181+
#undef check_mismatch
182+
135183
#define check_mismatch(x, ignore) \
136184
KUNIT_EXPECT_EQ_MSG(test, untouched->x, shuffled->x, \
137185
"Mismatched member value in %s initializer\n", \
@@ -266,7 +314,10 @@ static int randstruct_test_init(struct kunit *test)
266314
}
267315

268316
static struct kunit_case randstruct_test_cases[] = {
269-
KUNIT_CASE(randstruct_layout),
317+
KUNIT_CASE(randstruct_layout_same),
318+
KUNIT_CASE(randstruct_layout_mixed),
319+
KUNIT_CASE(randstruct_layout_fptr),
320+
KUNIT_CASE(randstruct_layout_fptr_deep),
270321
KUNIT_CASE(randstruct_initializers),
271322
{}
272323
};

0 commit comments

Comments
 (0)