mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
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 <broonie@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Link: https://lore.kernel.org/r/20250703-arm64-gcs-vfork-exit-v3-3-1e9a9d2ddbbe@kernel.org Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
This commit is contained in:
parent
696bf15792
commit
1536aa0fb1
1 changed files with 63 additions and 0 deletions
|
@ -298,6 +298,68 @@ out:
|
|||
return pass;
|
||||
}
|
||||
|
||||
/* A vfork()ed process can run and exit */
|
||||
static bool test_vfork(void)
|
||||
{
|
||||
unsigned long child_mode;
|
||||
int ret, status;
|
||||
pid_t pid;
|
||||
bool pass = true;
|
||||
|
||||
pid = vfork();
|
||||
if (pid == -1) {
|
||||
ksft_print_msg("vfork() failed: %d\n", errno);
|
||||
pass = false;
|
||||
goto out;
|
||||
}
|
||||
if (pid == 0) {
|
||||
/*
|
||||
* In child, make sure we can call a function, read
|
||||
* the GCS pointer and status and then exit.
|
||||
*/
|
||||
valid_gcs_function();
|
||||
get_gcspr();
|
||||
|
||||
ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
|
||||
&child_mode, 0, 0, 0);
|
||||
if (ret == 0 && !(child_mode & PR_SHADOW_STACK_ENABLE)) {
|
||||
ksft_print_msg("GCS not enabled in child\n");
|
||||
ret = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
_exit(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* In parent, check we can still do function calls then check
|
||||
* on the child.
|
||||
*/
|
||||
valid_gcs_function();
|
||||
|
||||
ksft_print_msg("Waiting for child %d\n", pid);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
if (ret == -1) {
|
||||
ksft_print_msg("Failed to wait for child: %d\n",
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WIFEXITED(status)) {
|
||||
ksft_print_msg("Child exited due to signal %d\n",
|
||||
WTERMSIG(status));
|
||||
pass = false;
|
||||
} else if (WEXITSTATUS(status)) {
|
||||
ksft_print_msg("Child exited with status %d\n",
|
||||
WEXITSTATUS(status));
|
||||
pass = false;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
typedef bool (*gcs_test)(void);
|
||||
|
||||
static struct {
|
||||
|
@ -314,6 +376,7 @@ static struct {
|
|||
{ "enable_invalid", enable_invalid, true },
|
||||
{ "map_guarded_stack", map_guarded_stack },
|
||||
{ "fork", test_fork },
|
||||
{ "vfork", test_vfork },
|
||||
};
|
||||
|
||||
int main(void)
|
||||
|
|
Loading…
Add table
Reference in a new issue