1 /* Test for (lack of) command execution in wordexp.
2 Copyright (C) 1997-2021 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>