Skip to content

Commit

Permalink
* elf/dl-error.c (_dl_signal_error): Store information about use of
Browse files Browse the repository at this point in the history
	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.
  • Loading branch information
Ulrich Drepper committed Jun 12, 2005
1 parent 6dffebd commit 74780cf
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 41 deletions.
18 changes: 18 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
6 changes: 4 additions & 2 deletions dlfcn/dlerror.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <dlfcn.h>
#include <libintl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -40,6 +41,7 @@ struct dl_action_result
{
int errcode;
int returned;
bool malloced;
const char *objname;
const char *errstring;
};
Expand Down Expand Up @@ -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;
Expand Down
31 changes: 20 additions & 11 deletions elf/dl-deps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand All @@ -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. */
Expand All @@ -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))
Expand All @@ -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
Expand Down
30 changes: 23 additions & 7 deletions elf/dl-error.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <libintl.h>
#include <setjmp.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
Expand All @@ -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. */
};

Expand All @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -162,13 +176,15 @@ _dl_catch_error (const char **objname, const char **errstring,
*catchp = old;
*objname = NULL;
*errstring = NULL;
*mallocedp = false;
return 0;
}

/* We get here only if we longjmp'd out of OPERATE. */
*catchp = old;
*objname = c.objname;
*errstring = c.errstring;
*mallocedp = c.malloced;
return errcode == -1 ? 0 : errcode;
}

Expand Down
11 changes: 6 additions & 5 deletions elf/dl-libc.c
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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;
Expand Down
15 changes: 8 additions & 7 deletions elf/dl-open.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()"));
Expand Down Expand Up @@ -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;
Expand All @@ -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. */
Expand Down Expand Up @@ -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);
Expand Down
32 changes: 25 additions & 7 deletions elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down Expand Up @@ -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;
Expand All @@ -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 ("\
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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
{
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 74780cf

Please sign in to comment.