powerpc: Remove power7 strstr optimization
[glibc.git] / elf / tst-env-setuid.c
blob43047c48f3ecd55591316356ac62cca21dfb9165
1 /* Copyright (C) 2012-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 /* Verify that correctly filter out unsafe environment variables defined
19 in unsecvars.h. */
21 #include <array_length.h>
22 #include <gnu/lib-names.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
28 #include <support/check.h>
29 #include <support/support.h>
30 #include <support/test-driver.h>
31 #include <support/capture_subprocess.h>
33 static char SETGID_CHILD[] = "setgid-child";
35 #define FILTERED_VALUE "some-filtered-value"
36 #define UNFILTERED_VALUE "some-unfiltered-value"
37 /* It assumes no other programs is being profile with a library with same
38 SONAME using the default folder. */
39 #ifndef PROFILE_LIB
40 # define PROFILE_LIB "tst-sonamemove-runmod2.so"
41 #endif
43 struct envvar_t
45 const char *env;
46 const char *value;
49 /* That is not an extensible list of all filtered out environment
50 variables. */
51 static const struct envvar_t filtered_envvars[] =
53 { "GLIBC_TUNABLES", FILTERED_VALUE },
54 { "LD_AUDIT", FILTERED_VALUE },
55 { "LD_HWCAP_MASK", FILTERED_VALUE },
56 { "LD_LIBRARY_PATH", FILTERED_VALUE },
57 { "LD_PRELOAD", FILTERED_VALUE },
58 { "LD_PROFILE", PROFILE_LIB },
59 { "MALLOC_ARENA_MAX", FILTERED_VALUE },
60 { "MALLOC_PERTURB_", FILTERED_VALUE },
61 { "MALLOC_TRACE", FILTERED_VALUE },
62 { "MALLOC_TRIM_THRESHOLD_", FILTERED_VALUE },
63 { "RES_OPTIONS", FILTERED_VALUE },
64 { "LD_DEBUG", "all" },
65 { "LD_DEBUG_OUTPUT", "/tmp/some-file" },
66 { "LD_WARN", FILTERED_VALUE },
67 { "LD_VERBOSE", FILTERED_VALUE },
68 { "LD_BIND_NOW", "0" },
69 { "LD_BIND_NOT", "1" },
72 static const struct envvar_t unfiltered_envvars[] =
74 /* Non longer supported option. */
75 { "LD_ASSUME_KERNEL", UNFILTERED_VALUE },
78 static int
79 test_child (void)
81 int ret = 0;
83 for (const struct envvar_t *e = filtered_envvars;
84 e != array_end (filtered_envvars);
85 e++)
87 const char *env = getenv (e->env);
88 if (env != NULL)
90 printf ("FAIL: filtered environment variable is not NULL: %s=%s\n",
91 e->env, env);
92 ret = 1;
96 for (const struct envvar_t *e = unfiltered_envvars;
97 e != array_end (unfiltered_envvars);
98 e++)
100 const char *env = getenv (e->env);
101 if (!(env != NULL && strcmp (env, e->value) == 0))
103 if (env == NULL)
104 printf ("FAIL: unfiltered environment variable %s is NULL\n",
105 e->env);
106 else
107 printf ("FAIL: unfiltered environment variable %s=%s != %s\n",
108 e->env, env, e->value);
110 ret = 1;
114 /* Also check if no profile file was created.
115 The parent sets LD_DEBUG_OUTPUT="/tmp/some-file"
116 which should be filtered. Then it falls back to "/var/tmp".
117 Note: LD_PROFILE is not supported for static binaries. */
119 char *profilepath = xasprintf ("/var/tmp/%s.profile", PROFILE_LIB);
120 if (!access (profilepath, R_OK))
122 printf ("FAIL: LD_PROFILE file at %s was created!\n", profilepath);
123 ret = 1;
125 free (profilepath);
128 return ret;
131 static int
132 do_test (int argc, char **argv)
134 /* For dynamic loader, the test requires --enable-hardcoded-path-in-tests so
135 the kernel sets the AT_SECURE on process initialization. */
136 if (argc >= 2 && strstr (argv[1], LD_SO) != 0)
137 FAIL_UNSUPPORTED ("dynamic test requires --enable-hardcoded-path-in-tests");
139 /* Setgid child process. */
140 if (argc == 2 && strcmp (argv[1], SETGID_CHILD) == 0)
142 if (getgid () == getegid ())
143 /* This can happen if the file system is mounted nosuid. */
144 FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
145 (intmax_t) getgid ());
147 int ret = test_child ();
149 if (ret != 0)
150 exit (1);
152 /* Special return code to make sure that the child executed all the way
153 through. */
154 exit (42);
156 else
158 for (const struct envvar_t *e = filtered_envvars;
159 e != array_end (filtered_envvars);
160 e++)
161 setenv (e->env, e->value, 1);
163 for (const struct envvar_t *e = unfiltered_envvars;
164 e != array_end (unfiltered_envvars);
165 e++)
166 setenv (e->env, e->value, 1);
168 /* Ensure that the profile output does not exist from a previous run
169 (e.g. if test_dir, which defaults to /tmp, is mounted nosuid.)
170 Note: support_capture_subprogram_self_sgid creates the SGID binary
171 in test_dir. */
173 char *profilepath = xasprintf ("/var/tmp/%s.profile", PROFILE_LIB);
174 unlink (profilepath);
175 free (profilepath);
178 int status = support_capture_subprogram_self_sgid (SETGID_CHILD);
180 if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
181 exit (EXIT_UNSUPPORTED);
183 if (WEXITSTATUS (status) != 42)
185 printf (" child failed with status %d\n",
186 WEXITSTATUS (status));
187 support_record_failure ();
190 return 0;
194 #define TEST_FUNCTION_ARGV do_test
195 #include <support/test-driver.c>