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
21 #include <array_length.h>
22 #include <gnu/lib-names.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. */
40 # define PROFILE_LIB "tst-sonamemove-runmod2.so"
49 /* That is not an extensible list of all filtered out environment
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
},
83 for (const struct envvar_t
*e
= filtered_envvars
;
84 e
!= array_end (filtered_envvars
);
87 const char *env
= getenv (e
->env
);
90 printf ("FAIL: filtered environment variable is not NULL: %s=%s\n",
96 for (const struct envvar_t
*e
= unfiltered_envvars
;
97 e
!= array_end (unfiltered_envvars
);
100 const char *env
= getenv (e
->env
);
101 if (!(env
!= NULL
&& strcmp (env
, e
->value
) == 0))
104 printf ("FAIL: unfiltered environment variable %s is NULL\n",
107 printf ("FAIL: unfiltered environment variable %s=%s != %s\n",
108 e
->env
, env
, e
->value
);
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
);
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 ();
152 /* Special return code to make sure that the child executed all the way
158 for (const struct envvar_t
*e
= filtered_envvars
;
159 e
!= array_end (filtered_envvars
);
161 setenv (e
->env
, e
->value
, 1);
163 for (const struct envvar_t
*e
= unfiltered_envvars
;
164 e
!= array_end (unfiltered_envvars
);
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
173 char *profilepath
= xasprintf ("/var/tmp/%s.profile", PROFILE_LIB
);
174 unlink (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 ();
194 #define TEST_FUNCTION_ARGV do_test
195 #include <support/test-driver.c>