Skip to content

Commit 9132c39

Browse files
committed
selftests/exec: Test for empty string on NULL argv
Test for the NULL argv argument producing a single empty string on exec. Cc: Eric Biederman <[email protected]> Cc: Shuah Khan <[email protected]> Cc: Yang Yingliang <[email protected]> Cc: Andrew Morton <[email protected]> Cc: [email protected] Signed-off-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/lkml/[email protected]
1 parent dcd46d8 commit 9132c39

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

tools/testing/selftests/exec/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir
1010
TEST_FILES := Makefile
1111

1212
TEST_GEN_PROGS += recursion-depth
13+
TEST_GEN_PROGS += null-argv
1314

1415
EXTRA_CLEAN := $(OUTPUT)/subdir.moved $(OUTPUT)/execveat.moved $(OUTPUT)/xxxxx* \
1516
$(OUTPUT)/S_I*.test
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Test that empty argvs are swapped out for a single empty string. */
3+
#include <stdio.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
#include <sys/wait.h>
7+
8+
#include "../kselftest.h"
9+
10+
#define FORK(exec) \
11+
do { \
12+
pid = fork(); \
13+
if (pid == 0) { \
14+
/* Child */ \
15+
exec; /* Some kind of exec */ \
16+
perror("# " #exec); \
17+
return 1; \
18+
} \
19+
check_result(pid, #exec); \
20+
} while (0)
21+
22+
void check_result(pid_t pid, const char *msg)
23+
{
24+
int wstatus;
25+
26+
if (pid == (pid_t)-1) {
27+
perror("# fork");
28+
ksft_test_result_fail("fork failed: %s\n", msg);
29+
return;
30+
}
31+
if (waitpid(pid, &wstatus, 0) < 0) {
32+
perror("# waitpid");
33+
ksft_test_result_fail("waitpid failed: %s\n", msg);
34+
return;
35+
}
36+
if (!WIFEXITED(wstatus)) {
37+
ksft_test_result_fail("child did not exit: %s\n", msg);
38+
return;
39+
}
40+
if (WEXITSTATUS(wstatus) != 0) {
41+
ksft_test_result_fail("non-zero exit: %s\n", msg);
42+
return;
43+
}
44+
ksft_test_result_pass("%s\n", msg);
45+
}
46+
47+
int main(int argc, char *argv[], char *envp[])
48+
{
49+
pid_t pid;
50+
static char * const args[] = { NULL };
51+
static char * const str[] = { "", NULL };
52+
53+
/* argc counting checks */
54+
if (argc < 1) {
55+
fprintf(stderr, "# FAIL: saw argc == 0 (old kernel?)\n");
56+
return 1;
57+
}
58+
if (argc != 1) {
59+
fprintf(stderr, "# FAIL: unknown argc (%d)\n", argc);
60+
return 1;
61+
}
62+
if (argv[0][0] == '\0') {
63+
/* Good, we found a NULL terminated string at argv[0]! */
64+
return 0;
65+
}
66+
67+
/* Test runner. */
68+
ksft_print_header();
69+
ksft_set_plan(5);
70+
71+
FORK(execve(argv[0], str, NULL));
72+
FORK(execve(argv[0], NULL, NULL));
73+
FORK(execve(argv[0], NULL, envp));
74+
FORK(execve(argv[0], args, NULL));
75+
FORK(execve(argv[0], args, envp));
76+
77+
ksft_exit(ksft_cnt.ksft_pass == ksft_plan);
78+
}

0 commit comments

Comments
 (0)