Skip to content

Commit fff37bd

Browse files
committed
selftests/harness: Fix fixture teardown
Make sure fixture teardowns are run when test cases failed, including when _metadata->teardown_parent is set to true. Make sure only one fixture teardown is run per test case, handling the case where the test child forks. Cc: Jakub Kicinski <[email protected]> Cc: Shengyu Li <[email protected]> Cc: Shuah Khan <[email protected]> Fixes: 72d7cb5 ("selftests/harness: Prevent infinite loop due to Assert in FIXTURE_TEARDOWN") Fixes: 0710a1a ("selftests/harness: Merge TEST_F_FORK() into TEST_F()") Reviewed-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/r/[email protected] Rule: add Link: https://lore.kernel.org/stable/20240506165518.474504-4-mic%40digikod.net Signed-off-by: Mickaël Salaün <[email protected]>
1 parent 7e4042a commit fff37bd

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

tools/testing/selftests/kselftest_harness.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,10 @@
382382
FIXTURE_DATA(fixture_name) self; \
383383
pid_t child = 1; \
384384
int status = 0; \
385-
bool jmp = false; \
385+
/* Makes sure there is only one teardown, even when child forks again. */ \
386+
bool *teardown = mmap(NULL, sizeof(*teardown), \
387+
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \
388+
*teardown = false; \
386389
memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
387390
if (setjmp(_metadata->env) == 0) { \
388391
/* Use the same _metadata. */ \
@@ -399,15 +402,16 @@
399402
_metadata->exit_code = KSFT_FAIL; \
400403
} \
401404
} \
402-
else \
403-
jmp = true; \
404405
if (child == 0) { \
405-
if (_metadata->setup_completed && !_metadata->teardown_parent && !jmp) \
406+
if (_metadata->setup_completed && !_metadata->teardown_parent && \
407+
__sync_bool_compare_and_swap(teardown, false, true)) \
406408
fixture_name##_teardown(_metadata, &self, variant->data); \
407409
_exit(0); \
408410
} \
409-
if (_metadata->setup_completed && _metadata->teardown_parent) \
411+
if (_metadata->setup_completed && _metadata->teardown_parent && \
412+
__sync_bool_compare_and_swap(teardown, false, true)) \
410413
fixture_name##_teardown(_metadata, &self, variant->data); \
414+
munmap(teardown, sizeof(*teardown)); \
411415
if (!WIFEXITED(status) && WIFSIGNALED(status)) \
412416
/* Forward signal to __wait_for_test(). */ \
413417
kill(getpid(), WTERMSIG(status)); \

0 commit comments

Comments
 (0)