This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Constructor of external lib called too early

On 29 July 2013 18:25, Dominik Vogt <> 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.

> 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.

You also have to make sure you don't traverse the environment if the
executed binary is suid.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]