mirror of git://sourceware.org/git/glibc.git
elf: Ignore LD_PROFILE if LD_PROFILE_OUTPUT is not set (bug 33797)
The previous default for LD_PROFILE_OUTPUT, /var/tmp, is insecure because it's typically a 1777 directory, and other systems could place malicious files there which interfere with execution. Requiring the user to specify a profiling directory mitigates the impact of bug 33797. Clear LD_PROFILE_OUTPUT alongside with LD_PROFILE. Rework the test not to use predictable file names. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
parent
0bbeb1fd13
commit
7b543dcdf9
6
NEWS
6
NEWS
|
|
@ -100,7 +100,11 @@ Deprecated and removed features, and other changes affecting compatibility:
|
|||
|
||||
Changes to build and runtime requirements:
|
||||
|
||||
[Add changes to build and runtime requirements here]
|
||||
* The LD_PROFILE functionality no longer has a default directory for the
|
||||
profile data it writes. Instead, developers are required to set a
|
||||
directory explicitly using the LD_PROFILE_OUTPUT environment variable.
|
||||
To restore the previous, insecure behavior, processes can be run with
|
||||
LD_PROFILE_OUTPUT=/var/tmp.
|
||||
|
||||
Security related changes:
|
||||
|
||||
|
|
|
|||
10
elf/rtld.c
10
elf/rtld.c
|
|
@ -359,7 +359,6 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
|
|||
._dl_fpu_control = _FPU_DEFAULT,
|
||||
._dl_pagesize = EXEC_PAGESIZE,
|
||||
._dl_inhibit_cache = 0,
|
||||
._dl_profile_output = "/var/tmp",
|
||||
|
||||
/* Function pointers. */
|
||||
._dl_debug_printf = _dl_debug_printf,
|
||||
|
|
@ -2708,6 +2707,15 @@ process_envvars_default (struct dl_main_state *state)
|
|||
}
|
||||
}
|
||||
|
||||
/* There is no fixed, safe directory to store profiling data, so
|
||||
activate LD_PROFILE only if LD_PROFILE_OUTPUT is set as well. */
|
||||
if (GLRO(dl_profile) != NULL && GLRO(dl_profile_output) == NULL)
|
||||
{
|
||||
_dl_error_printf ("\
|
||||
warning: LD_PROFILE ignored because LD_PROFILE_OUTPUT not specified\n");
|
||||
GLRO(dl_profile) = NULL;
|
||||
}
|
||||
|
||||
/* If we have to run the dynamic linker in debugging mode and the
|
||||
LD_DEBUG_OUTPUT environment variable is given, we write the debug
|
||||
messages to this file. */
|
||||
|
|
|
|||
|
|
@ -40,7 +40,11 @@ static char SETGID_CHILD[] = "setgid-child";
|
|||
# define PROFILE_LIB "tst-sonamemove-runmod2.so"
|
||||
#endif
|
||||
|
||||
#define LD_DEBUG_OUTPUT "/tmp/some-file"
|
||||
/* Computed path for LD_DEBUG_OUTPUT. */
|
||||
static char *debugoutputpath;
|
||||
|
||||
/* Expected file name for erroneous LD_PROFILE output. */
|
||||
static char *profilepath;
|
||||
|
||||
struct envvar_t
|
||||
{
|
||||
|
|
@ -57,13 +61,14 @@ static const struct envvar_t filtered_envvars[] =
|
|||
{ "LD_LIBRARY_PATH", FILTERED_VALUE },
|
||||
{ "LD_PRELOAD", FILTERED_VALUE },
|
||||
{ "LD_PROFILE", PROFILE_LIB },
|
||||
{ "LD_PROFILE_OUTPUT", "/var/tmp" }, /* Not actually used. */
|
||||
{ "MALLOC_ARENA_MAX", FILTERED_VALUE },
|
||||
{ "MALLOC_PERTURB_", FILTERED_VALUE },
|
||||
{ "MALLOC_TRACE", FILTERED_VALUE },
|
||||
{ "MALLOC_TRIM_THRESHOLD_", FILTERED_VALUE },
|
||||
{ "RES_OPTIONS", FILTERED_VALUE },
|
||||
{ "LD_DEBUG", "all" },
|
||||
{ "LD_DEBUG_OUTPUT", LD_DEBUG_OUTPUT },
|
||||
{ "LD_DEBUG_OUTPUT", "overwritten" }, /* Not actually used. */
|
||||
{ "LD_WARN", FILTERED_VALUE },
|
||||
{ "LD_VERBOSE", FILTERED_VALUE },
|
||||
{ "LD_BIND_NOW", "0" },
|
||||
|
|
@ -79,7 +84,7 @@ static const struct envvar_t unfiltered_envvars[] =
|
|||
static void
|
||||
unlink_ld_debug_output (pid_t pid)
|
||||
{
|
||||
char *output = xasprintf ("%s.%d", LD_DEBUG_OUTPUT, pid);
|
||||
char *output = xasprintf ("%s.%d", debugoutputpath, pid);
|
||||
unlink (output);
|
||||
free (output);
|
||||
}
|
||||
|
|
@ -121,18 +126,12 @@ test_child (void)
|
|||
}
|
||||
|
||||
/* Also check if no profile file was created.
|
||||
The parent sets LD_DEBUG_OUTPUT="/tmp/some-file"
|
||||
which should be filtered. Then it falls back to "/var/tmp".
|
||||
Note: LD_PROFILE is not supported for static binaries. */
|
||||
{
|
||||
char *profilepath = xasprintf ("/var/tmp/%s.profile", PROFILE_LIB);
|
||||
if (!access (profilepath, R_OK))
|
||||
{
|
||||
printf ("FAIL: LD_PROFILE file at %s was created!\n", profilepath);
|
||||
ret = 1;
|
||||
}
|
||||
free (profilepath);
|
||||
}
|
||||
if (!access (profilepath, R_OK))
|
||||
{
|
||||
printf ("FAIL: LD_PROFILE file at %s was created!\n", profilepath);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -145,6 +144,11 @@ do_test (int argc, char **argv)
|
|||
if (argc >= 2 && strstr (argv[1], LD_SO) != 0)
|
||||
FAIL_UNSUPPORTED ("dynamic test requires --enable-hardcoded-path-in-tests");
|
||||
|
||||
profilepath = xasprintf ("%s/%s.profile",
|
||||
support_objdir_root, PROFILE_LIB);
|
||||
debugoutputpath = xasprintf ("%s/tst-env-setuid-file",
|
||||
support_objdir_root);
|
||||
|
||||
/* Setgid child process. */
|
||||
if (argc == 2 && strcmp (argv[1], SETGID_CHILD) == 0)
|
||||
{
|
||||
|
|
@ -165,7 +169,6 @@ do_test (int argc, char **argv)
|
|||
|
||||
if (ret != 0)
|
||||
exit (1);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -179,20 +182,25 @@ do_test (int argc, char **argv)
|
|||
e++)
|
||||
setenv (e->env, e->value, 1);
|
||||
|
||||
/* Dynamically computed values. */
|
||||
setenv ("LD_DEBUG_OUTPUT", debugoutputpath, 1);
|
||||
setenv ("LD_PROFILE_OUTPUT", support_objdir_root, 1);
|
||||
|
||||
/* Ensure that the profile output does not exist from a previous run
|
||||
(e.g. if test_dir, which defaults to /tmp, is mounted nosuid.)
|
||||
Note: support_capture_subprogram_self_sgid creates the SGID binary
|
||||
in test_dir. */
|
||||
{
|
||||
char *profilepath = xasprintf ("/var/tmp/%s.profile", PROFILE_LIB);
|
||||
unlink (profilepath);
|
||||
free (profilepath);
|
||||
}
|
||||
unlink (profilepath);
|
||||
|
||||
support_capture_subprogram_self_sgid (SETGID_CHILD);
|
||||
|
||||
return 0;
|
||||
/* And clean up afterwards if necessary. */
|
||||
unlink (profilepath);
|
||||
}
|
||||
|
||||
free (profilepath);
|
||||
free (debugoutputpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION_ARGV do_test
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"LD_ORIGIN_PATH\0" \
|
||||
"LD_PRELOAD\0" \
|
||||
"LD_PROFILE\0" \
|
||||
"LD_PROFILE_OUTPUT\0" \
|
||||
"LD_SHOW_AUXV\0" \
|
||||
"LD_VERBOSE\0" \
|
||||
"LD_WARN\0" \
|
||||
|
|
|
|||
Loading…
Reference in New Issue