1 /* Test for (lack of) command execution in wordexp.
2 Copyright (C) 1997-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* This test optionally counts PIDs in a PID namespace to detect
20 forks. Without kernel support for that, it will merely look at the
21 error codes from wordexp to check that no command execution
28 #include <support/check.h>
29 #include <support/namespace.h>
30 #include <support/xunistd.h>
33 /* Set to true if the test runs in a PID namespace and can therefore
34 use next_pid below. */
35 static bool pid_tests_supported
;
37 /* The next PID, as returned from next_pid below. Only meaningful if
38 pid_tests_supported. */
39 static pid_t expected_pid
;
41 /* Allocate the next PID and return it. The process is terminated.
42 Note that the test itself advances the next PID. */
49 xwaitpid (pid
, NULL
, 0);
53 /* Check that evaluating PATTERN with WRDE_NOCMD results in
56 expect_failure (const char *pattern
, int expected_error
)
58 printf ("info: testing pattern: %s\n", pattern
);
60 TEST_COMPARE (wordexp (pattern
, &w
, WRDE_NOCMD
), expected_error
);
61 if (pid_tests_supported
)
62 TEST_COMPARE (expected_pid
++, next_pid ());
65 /* Run all the tests. Invoked with different IFS values. */
69 /* Integer overflow in division. */
71 static const char *const numbers
[] = {
77 "9223372036854775808",
78 "18446744073709551616",
79 "170141183460469231731687303715884105728",
80 "340282366920938463463374607431768211456",
84 for (const char *const *num
= numbers
; *num
!= NULL
; ++num
)
88 snprintf (pattern
, sizeof (pattern
), "$[(-%s)/(-1)]", *num
);
89 int ret
= wordexp (pattern
, &w
, WRDE_NOCMD
);
92 /* If the call is successful, the result must match the
94 TEST_COMPARE (w
.we_wordc
, 1);
95 TEST_COMPARE_STRING (w
.we_wordv
[0], *num
);
96 TEST_COMPARE_STRING (w
.we_wordv
[1], NULL
);
100 /* Otherwise, the test must fail with a syntax error. */
101 TEST_COMPARE (ret
, WRDE_SYNTAX
);
103 /* In both cases, command execution is not permitted. */
104 if (pid_tests_supported
)
105 TEST_COMPARE (expected_pid
++, next_pid ());
109 /* (Lack of) command execution tests. */
111 expect_failure ("$(ls)", WRDE_CMDSUB
);
113 /* Test for CVE-2014-7817. We test 3 combinations of command
114 substitution inside an arithmetic expression to make sure that
115 no commands are executed and error is returned. */
116 expect_failure ("$((`echo 1`))", WRDE_CMDSUB
);
117 expect_failure ("$((1+`echo 1`))", WRDE_CMDSUB
);
118 expect_failure ("$((1+$((`echo 1`))))", WRDE_CMDSUB
);
120 expect_failure ("$[1/0]", WRDE_SYNTAX
); /* BZ 18100. */
124 subprocess (void *closure
)
127 if (pid_tests_supported
)
128 TEST_COMPARE (expected_pid
++, next_pid ());
130 /* Check that triggering command execution via wordexp results in a
132 if (pid_tests_supported
)
135 TEST_COMPARE (wordexp ("$(echo Test)", &w
, 0), 0);
136 TEST_COMPARE (w
.we_wordc
, 1);
137 TEST_COMPARE_STRING (w
.we_wordv
[0], "Test");
138 TEST_COMPARE_STRING (w
.we_wordv
[1], NULL
);
141 pid_t n
= next_pid ();
142 printf ("info: self-test resulted in PID %d (processes created: %d)\n",
143 (int) n
, (int) (n
- expected_pid
));
144 TEST_VERIFY (n
> expected_pid
);
145 expected_pid
= n
+ 1;
148 puts ("info: testing without IFS");
152 puts ("info: testing with IFS");
153 TEST_COMPARE (setenv ("IFS", " \t\n", 1), 0);
160 support_become_root ();
163 if (unshare (CLONE_NEWPID
) != 0)
164 printf ("warning: unshare (CLONE_NEWPID) failed: %m\n"
165 "warning: This leads to reduced test coverage.\n");
167 pid_tests_supported
= true;
169 printf ("warning: CLONE_NEWPID not available.\n"
170 "warning: This leads to reduced test coverage.\n");
173 /* CLONE_NEWPID only has an effect after fork. */
174 support_isolate_in_subprocess (subprocess
, NULL
);
179 #include <support/test-driver.c>