* elf/dl-error.c (_dl_signal_error): Store information about use of

real malloc in the catch object.
	(_dl_catch_error): Forward information about malloc use to caller
	in new parameter.
	(_dl_out_of_memory): Make static.
	* elf/dl-deps.c: Adjust callers of _dl_catch_error.
	* elf/dl-libc.c: Likewise.
	* elf/dl-open.c: Likewise.
	* elf/rtld.c: Likewise.
	Add new --audit option.
	* sysdeps/generic/ldsodefs.h: Remove _dl_out_of_memory declaration.
	(rtld_global_ro._dl_signal_error): Add new parameter.
	* include/dlfcn.h (_dl_catch_error): Add new parameter.
	* dlfcn/dlfcn.c (_dlerror_run): Pass additional parameter to
	_dl_catch_error.  Only free if the returned newly value says so.
This commit is contained in:
Ulrich Drepper 2005-06-12 16:29:51 +00:00
parent 6dffebd8b4
commit 74780cf659
8 changed files with 108 additions and 41 deletions

View File

@ -1,3 +1,21 @@
2005-06-12 Ulrich Drepper <drepper@redhat.com>
* elf/dl-error.c (_dl_signal_error): Store information about use of
real malloc in the catch object.
(_dl_catch_error): Forward information about malloc use to caller
in new parameter.
(_dl_out_of_memory): Make static.
* elf/dl-deps.c: Adjust callers of _dl_catch_error.
* elf/dl-libc.c: Likewise.
* elf/dl-open.c: Likewise.
* elf/rtld.c: Likewise.
Add new --audit option.
* sysdeps/generic/ldsodefs.h: Remove _dl_out_of_memory declaration.
(rtld_global_ro._dl_signal_error): Add new parameter.
* include/dlfcn.h (_dl_catch_error): Add new parameter.
* dlfcn/dlfcn.c (_dlerror_run): Pass additional parameter to
_dl_catch_error. Only free if the returned newly value says so.
2005-06-01 Roland McGrath <roland@redhat.com>
[BZ #959]

View File

@ -19,6 +19,7 @@
#include <dlfcn.h>
#include <libintl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -40,6 +41,7 @@ struct dl_action_result
{
int errcode;
int returned;
bool malloced;
const char *objname;
const char *errstring;
};
@ -154,13 +156,13 @@ _dlerror_run (void (*operate) (void *), void *args)
{
/* Free the error string from the last failed command. This can
happen if `dlerror' was not run after an error was found. */
if (strcmp (result->errstring, "out of memory") != 0)
if (result->malloced)
free ((char *) result->errstring);
result->errstring = NULL;
}
result->errcode = GLRO(dl_catch_error) (&result->objname, &result->errstring,
operate, args);
&result->malloced, operate, args);
/* If no error we mark that no error string is available. */
result->returned = result->errstring == NULL;

View File

@ -235,16 +235,22 @@ _dl_map_object_deps (struct link_map *map,
{
/* Map in the needed object. */
struct link_map *dep;
int err;
/* Recognize DSTs. */
name = expand_dst (l, strtab + d->d_un.d_val, 0);
/* Store the tag in the argument structure. */
args.name = name;
err = _dl_catch_error (&objname, &errstring, openaux, &args);
bool malloced;
int err = _dl_catch_error (&objname, &errstring, &malloced,
openaux, &args);
if (__builtin_expect (errstring != NULL, 0))
{
char *new_errstring = strdupa (errstring);
if (malloced)
free ((char *) errstring);
errstring = new_errstring;
if (err)
errno_reason = err;
else
@ -288,8 +294,6 @@ _dl_map_object_deps (struct link_map *map,
if (d->d_tag == DT_AUXILIARY)
{
int err;
/* Say that we are about to load an auxiliary library. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
0))
@ -301,13 +305,14 @@ _dl_map_object_deps (struct link_map *map,
/* We must be prepared that the addressed shared
object is not available. */
err = _dl_catch_error (&objname, &errstring, openaux,
&args);
bool malloced;
(void) _dl_catch_error (&objname, &errstring, &malloced,
openaux, &args);
if (__builtin_expect (errstring != NULL, 0))
{
/* We are not interested in the error message. */
assert (errstring != NULL);
if (errstring != _dl_out_of_memory)
if (malloced)
free ((char *) errstring);
/* Simply ignore this error and continue the work. */
@ -316,8 +321,6 @@ _dl_map_object_deps (struct link_map *map,
}
else
{
int err;
/* Say that we are about to load an auxiliary library. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
0))
@ -328,10 +331,16 @@ _dl_map_object_deps (struct link_map *map,
? l->l_name : rtld_progname);
/* For filter objects the dependency must be available. */
err = _dl_catch_error (&objname, &errstring, openaux,
&args);
bool malloced;
int err = _dl_catch_error (&objname, &errstring, &malloced,
openaux, &args);
if (__builtin_expect (errstring != NULL, 0))
{
char *new_errstring = strdupa (errstring);
if (malloced)
free ((char *) errstring);
errstring = new_errstring;
if (err)
errno_reason = err;
else

View File

@ -19,6 +19,7 @@
#include <libintl.h>
#include <setjmp.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -30,6 +31,8 @@ struct catch
{
const char *objname; /* Object/File name. */
const char *errstring; /* Error detail filled in here. */
bool malloced; /* Nonzero if the string is malloced
by the libc malloc. */
jmp_buf env; /* longjmp here on error. */
};
@ -44,8 +47,7 @@ struct catch
/* This message we return as a last resort. We define the string in a
variable since we have to avoid freeing it and so have to enable
a pointer comparison. See below and in dlfcn/dlerror.c. */
const char _dl_out_of_memory[] = "out of memory";
rtld_hidden_data_def (_dl_out_of_memory)
static const char _dl_out_of_memory[] = "out of memory";
/* This points to a function which is called when an continuable error is
@ -87,15 +89,27 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
lcatch->errstring = (char *) malloc (len_objname + len_errstring);
if (lcatch->errstring != NULL)
/* Make a copy of the object file name and the error string. */
lcatch->objname = memcpy (__mempcpy ((char *) lcatch->errstring,
errstring, len_errstring),
objname, len_objname);
{
/* Make a copy of the object file name and the error string. */
lcatch->objname = memcpy (__mempcpy ((char *) lcatch->errstring,
errstring, len_errstring),
objname, len_objname);
/* If the main executable is relocated it means the libc's malloc
is used. */
#ifdef SHARED
lcatch->malloced = (GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_relocated
!= 0);
#else
lcatch->malloced = true;
#endif
}
else
{
/* This is better than nothing. */
lcatch->objname = "";
lcatch->errstring = _dl_out_of_memory;
lcatch->malloced = false;
}
longjmp (lcatch->env, errcode ?: -1);
}
@ -140,7 +154,7 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
int
internal_function
_dl_catch_error (const char **objname, const char **errstring,
void (*operate) (void *), void *args)
bool *mallocedp, void (*operate) (void *), void *args)
{
int errcode;
struct catch *volatile old;
@ -162,6 +176,7 @@ _dl_catch_error (const char **objname, const char **errstring,
*catchp = old;
*objname = NULL;
*errstring = NULL;
*mallocedp = false;
return 0;
}
@ -169,6 +184,7 @@ _dl_catch_error (const char **objname, const char **errstring,
*catchp = old;
*objname = c.objname;
*errstring = c.errstring;
*mallocedp = c.malloced;
return errcode == -1 ? 0 : errcode;
}

View File

@ -1,5 +1,5 @@
/* Handle loading and unloading shared objects for internal libc purposes.
Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Copyright (C) 1999,2000,2001,2002,2004,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.
@ -42,12 +42,13 @@ dlerror_run (void (*operate) (void *), void *args)
{
const char *objname;
const char *last_errstring = NULL;
int result;
bool malloced;
(void) GLRO(dl_catch_error) (&objname, &last_errstring, operate, args);
(void) GLRO(dl_catch_error) (&objname, &last_errstring, &malloced,
operate, args);
result = last_errstring != NULL;
if (result && last_errstring != _dl_out_of_memory)
int result = last_errstring != NULL;
if (result && malloced)
free ((char *) last_errstring);
return result;

View File

@ -504,11 +504,6 @@ void *
_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
int argc, char *argv[], char *env[])
{
struct dl_open_args args;
const char *objname;
const char *errstring;
int errcode;
if ((mode & RTLD_BINDING_MASK) == 0)
/* One of the flags must be set. */
_dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()"));
@ -543,6 +538,7 @@ no more namespaces available for dlmopen()"));
_dl_signal_error (EINVAL, file, NULL,
N_("invalid target namespace in dlmopen()"));
struct dl_open_args args;
args.file = file;
args.mode = mode;
args.caller_dlopen = caller_dlopen;
@ -552,7 +548,12 @@ no more namespaces available for dlmopen()"));
args.argc = argc;
args.argv = argv;
args.env = env;
errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args);
const char *objname;
const char *errstring;
bool malloced;
int errcode = _dl_catch_error (&objname, &errstring, &malloced,
dl_open_worker, &args);
#ifndef MAP_COPY
/* We must munmap() the cache file. */
@ -603,7 +604,7 @@ no more namespaces available for dlmopen()"));
memcpy (local_errstring, errstring, len_errstring);
}
if (errstring != _dl_out_of_memory)
if (malloced)
free ((char *) errstring);
assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);

View File

@ -61,6 +61,9 @@ static void print_missing_version (int errcode, const char *objname,
/* Print the various times we collected. */
static void print_statistics (hp_timing_t *total_timep);
/* Add audit objects. */
static void process_dl_audit (char *str);
/* This is a list of all the modes the dynamic loader can be in. */
enum mode { normal, list, verify, trace };
@ -771,6 +774,7 @@ do_preload (char *fname, struct link_map *main_map, const char *where)
const char *objname;
const char *err_str = NULL;
struct map_args args;
bool malloced;
args.str = fname;
args.loader = main_map;
@ -779,7 +783,7 @@ do_preload (char *fname, struct link_map *main_map, const char *where)
unsigned int old_nloaded = GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
(void) _dl_catch_error (&objname, &err_str, map_doit, &args);
(void) _dl_catch_error (&objname, &err_str, &malloced, map_doit, &args);
if (__builtin_expect (err_str != NULL, 0))
{
_dl_error_printf ("\
@ -923,6 +927,14 @@ dl_main (const ElfW(Phdr) *phdr,
{
GLRO(dl_inhibit_rpath) = INTUSE(_dl_argv)[2];
_dl_skip_args += 2;
_dl_argc -= 2;
INTUSE(_dl_argv) += 2;
}
else if (! strcmp (INTUSE(_dl_argv)[1], "--audit") && _dl_argc > 2)
{
process_dl_audit (INTUSE(_dl_argv)[2]);
_dl_skip_args += 2;
_dl_argc -= 2;
INTUSE(_dl_argv) += 2;
@ -983,12 +995,14 @@ of this helper program; chances are you did not intend to run this program.\n\
const char *objname;
const char *err_str = NULL;
struct map_args args;
bool malloced;
args.str = rtld_progname;
args.loader = NULL;
args.is_preloaded = 0;
args.mode = __RTLD_OPENEXEC;
(void) _dl_catch_error (&objname, &err_str, map_doit, &args);
(void) _dl_catch_error (&objname, &err_str, &malloced, map_doit,
&args);
if (__builtin_expect (err_str != NULL, 0))
/* We don't free the returned string, the programs stops
anyway. */
@ -1398,14 +1412,17 @@ ld.so does not support TLS, but program uses it!\n");
const char *objname;
const char *err_str = NULL;
(void) _dl_catch_error (&objname, &err_str, dlmopen_doit, &dlmargs);
bool malloced;
(void) _dl_catch_error (&objname, &err_str, &malloced, dlmopen_doit,
&dlmargs);
if (__builtin_expect (err_str != NULL, 0))
{
not_loaded:
_dl_error_printf ("\
ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
al->name, err_str);
free ((char *) err_str);
if (malloced)
free ((char *) err_str);
}
else
{
@ -1414,7 +1431,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
largs.map = dlmargs.map;
/* Check whether the interface version matches. */
(void) _dl_catch_error (&objname, &err_str, lookup_doit, &largs);
(void) _dl_catch_error (&objname, &err_str, &malloced,
lookup_doit, &largs);
unsigned int (*laversion) (unsigned int);
unsigned int lav;
@ -1455,8 +1473,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
do
{
largs.name = cp;
(void) _dl_catch_error (&objname, &err_str, lookup_doit,
&largs);
(void) _dl_catch_error (&objname, &err_str, &malloced,
lookup_doit, &largs);
/* Store the pointer. */
if (err_str == NULL && largs.result != NULL)

View File

@ -1,6 +1,7 @@
#ifndef _DLFCN_H
#include <dlfcn/dlfcn.h>
#include <link.h> /* For ElfW. */
#include <stdbool.h>
/* Internally used flag. */
#define __RTLD_DLOPEN 0x80000000
@ -67,9 +68,10 @@ extern void *_dl_vsym (void *handle, const char *name, const char *version,
and the error code passed is the return value and *OBJNAME is set to
the object name which experienced the problems. ERRSTRING if nonzero
points to a malloc'ed string which the caller has to free after use.
ARGS is passed as argument to OPERATE. */
ARGS is passed as argument to OPERATE. MALLOCEDP is set to true only
if the returned string is allocated using the libc's malloc. */
extern int _dl_catch_error (const char **objname, const char **errstring,
void (*operate) (void *),
bool *mallocedp, void (*operate) (void *),
void *args)
internal_function;