Skip to content

Commit 1536aa0

Browse files
brooniet-8ch
authored andcommitted
kselftest/arm64: Add a test for vfork() with GCS
Ensure that we've got at least some coverage of the special cases around vfork() by adding a test case in basic-gcs doing the same thing as the plain fork() one - vfork(), do a few checks and then return to the parent. Signed-off-by: Mark Brown <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Thomas Weißschuh <[email protected]>
1 parent 696bf15 commit 1536aa0

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

tools/testing/selftests/arm64/gcs/basic-gcs.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,68 @@ static bool test_fork(void)
298298
return pass;
299299
}
300300

301+
/* A vfork()ed process can run and exit */
302+
static bool test_vfork(void)
303+
{
304+
unsigned long child_mode;
305+
int ret, status;
306+
pid_t pid;
307+
bool pass = true;
308+
309+
pid = vfork();
310+
if (pid == -1) {
311+
ksft_print_msg("vfork() failed: %d\n", errno);
312+
pass = false;
313+
goto out;
314+
}
315+
if (pid == 0) {
316+
/*
317+
* In child, make sure we can call a function, read
318+
* the GCS pointer and status and then exit.
319+
*/
320+
valid_gcs_function();
321+
get_gcspr();
322+
323+
ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
324+
&child_mode, 0, 0, 0);
325+
if (ret == 0 && !(child_mode & PR_SHADOW_STACK_ENABLE)) {
326+
ksft_print_msg("GCS not enabled in child\n");
327+
ret = EXIT_FAILURE;
328+
}
329+
330+
_exit(ret);
331+
}
332+
333+
/*
334+
* In parent, check we can still do function calls then check
335+
* on the child.
336+
*/
337+
valid_gcs_function();
338+
339+
ksft_print_msg("Waiting for child %d\n", pid);
340+
341+
ret = waitpid(pid, &status, 0);
342+
if (ret == -1) {
343+
ksft_print_msg("Failed to wait for child: %d\n",
344+
errno);
345+
return false;
346+
}
347+
348+
if (!WIFEXITED(status)) {
349+
ksft_print_msg("Child exited due to signal %d\n",
350+
WTERMSIG(status));
351+
pass = false;
352+
} else if (WEXITSTATUS(status)) {
353+
ksft_print_msg("Child exited with status %d\n",
354+
WEXITSTATUS(status));
355+
pass = false;
356+
}
357+
358+
out:
359+
360+
return pass;
361+
}
362+
301363
typedef bool (*gcs_test)(void);
302364

303365
static struct {
@@ -314,6 +376,7 @@ static struct {
314376
{ "enable_invalid", enable_invalid, true },
315377
{ "map_guarded_stack", map_guarded_stack },
316378
{ "fork", test_fork },
379+
{ "vfork", test_vfork },
317380
};
318381

319382
int main(void)

0 commit comments

Comments
 (0)