This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: Constructor of external lib called too early
- From: Dominik Vogt <vogt at linux dot vnet dot ibm dot com>
- To: libc-help <libc-help at sourceware dot org>
- Cc: Siddhesh Poyarekar <siddhesh dot poyarekar at gmail dot com>
- Date: Tue, 30 Jul 2013 10:35:37 +0200
- Subject: Re: Constructor of external lib called too early
- References: <20130729125543 dot GA24620 at linux dot vnet dot ibm dot com> <CAAHN_R2MMfomN9u=KnEWXUo=GpJP33WJEkrSX9AQj-Nsmna4tQ at mail dot gmail dot com>
- Reply-to: vogt at linux dot vnet dot ibm dot com
On Mon, Jul 29, 2013 at 06:46:56PM +0530, Siddhesh Poyarekar wrote:
> On 29 July 2013 18:25, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> > An external library - say, libfoo.{a,so} - defines a costructor
> >
> > static void __attribute__ ((constructor 65535))
> > __foo_ctor (void)
> > {
> > const char *val;
> >
> > val = getenv ("FOO_CFG");
> > ...
> > }
> >
> > and glibc is built and linked with -lfoo.
> >
> > A program is linked against that the modified glibc. Now, when
> > the program is started, at the time __foo_ctor is called, the
> > environment is empty and FOO is never evaluated. I guess this
> > means that the constructor is called before the environment is
> > initialized.
>
> Yes, and it is because glibc depends on this library and is hence
> initialized after the library. The glibc _init initializes __environ.
Understood.
> > Is there a way / what is the right way to have __foo_ctor called
> > _after_ the initialization of the environment? (Note that calling
> > the constructor from the executable instead of from glibc is not
> > an option.)
>
> The constructors are usually called like this from the linker:
>
> if (l->l_info[DT_INIT] != NULL)
> {
> init_t init = (init_t) DL_DT_INIT_ADDRESS
> (l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
>
> /* Call the function. */
> init (argc, argv, env);
> }
>
> So if your constructor accepts argc, argv and envp, you might be able
> to get the environment from its argument. This is a NULL terminated
> array, so you will have to do your own traversal and matching. I
> don't know if this is documented anywhere, so I don't know if it is
> the canonical way to do this.
Okay, that works nicely, thanks.
> You also have to make sure you don't traverse the environment if the
> executed binary is suid.
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt
IBM Germany