From: Song Hu <[email protected]> When fork() fails and returns -1, the code falls into the else branch and stores -1 into self->pids[i]. Later, kill(-1, SIGTERM) is called which sends SIGTERM to every process the user has permission to signal, potentially killing the entire user session.
Add an explicit check for fork() returning -1 (pid < 0). On failure, clean up any already-forked children before failing the test via ASSERT_GE(pid, 0). This fix is applied to all three fork() call sites in shared_anon, shared_anon_thp, and shared_anon_htlb tests. Signed-off-by: Hu Song <[email protected]> --- tools/testing/selftests/mm/migration.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c index 60e78bbfc0e3..f433e4f195ad 100644 --- a/tools/testing/selftests/mm/migration.c +++ b/tools/testing/selftests/mm/migration.c @@ -163,6 +163,11 @@ TEST_F_TIMEOUT(migration, shared_anon, 2*RUNTIME) memset(ptr, 0xde, TWOMEG); for (i = 0; i < self->nthreads - 1; i++) { pid = fork(); + if (pid < 0) { + while (--i >= 0) + kill(self->pids[i], SIGTERM); + ASSERT_GE(pid, 0); + } if (!pid) { prctl(PR_SET_PDEATHSIG, SIGHUP); /* Parent may have died before prctl so check now. */ @@ -235,6 +240,11 @@ TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME) memset(ptr, 0xde, TWOMEG); for (i = 0; i < self->nthreads - 1; i++) { pid = fork(); + if (pid < 0) { + while (--i >= 0) + kill(self->pids[i], SIGTERM); + ASSERT_GE(pid, 0); + } if (!pid) { prctl(PR_SET_PDEATHSIG, SIGHUP); /* Parent may have died before prctl so check now. */ @@ -295,6 +305,11 @@ TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME) memset(ptr, 0xde, TWOMEG); for (i = 0; i < self->nthreads - 1; i++) { pid = fork(); + if (pid < 0) { + while (--i >= 0) + kill(self->pids[i], SIGTERM); + ASSERT_GE(pid, 0); + } if (!pid) { prctl(PR_SET_PDEATHSIG, SIGHUP); /* Parent may have died before prctl so check now. */ -- 2.25.1

