diff mbox series

[uclibc-ng-devel,1/2] Make getauxval work with static linking

Message ID 20250303154154.18427-1-marcus.haehnel@kernkonzept.com
State Accepted
Headers show
Series [uclibc-ng-devel,1/2] Make getauxval work with static linking | expand

Commit Message

Marcus Haehnel March 3, 2025, 3:41 p.m. UTC
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>

While for dynamic linking the _dl_auxvt array is provided in
dl-startup.c as part of the ldso, is was undefined for statically
linked binaries. This resulted in a corresponding linker error if
a statically linked program used getauxval.

To provide _dl_auxvt also for statically linked binaries, a definition
of _dl_auxvt is added to dl-support.c and initialized by _dl_aux_init().

Signed-off-by: Marcus Haehnel <marcus.haehnel@kernkonzept.com>
---
 libc/misc/elf/dl-support.c          | 16 +++++++++++++---
 libc/misc/internals/__uClibc_main.c | 22 ++++++----------------
 2 files changed, 19 insertions(+), 19 deletions(-)

Comments

Waldemar Brodkorb March 6, 2025, 1:08 p.m. UTC | #1
Hi Marcus,

I accidentally pushed the changes and now get following build error:

libc/misc/internals/__uClibc_main.c: In function '__uClibc_main':
libc/misc/internals/__uClibc_main.c:424:10: error: '_dl_auxvt' undeclared (first use in this function); did you mean '_dl_aux_init'?
  424 |     if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
      |          ^~~~~~~~~
      |          _dl_aux_init
libc/misc/internals/__uClibc_main.c:424:10: note: each undeclared identifier is reported only once for each function it appears in
gmake[6]: *** [Makerules:373: libc/misc/internals/__uClibc_main.os] Error 1
gmake[5]: *** [Makefile:353: /home/wbx/embedded-test/openadk/toolchain_build_qemu-aarch64_uclibc-ng_cortex_a53/w-uClibc-ng-1.0.51-1/uClibc-ng-1.0.51/.compiled] Error 2
gmake[4]: *** [Makefile:106: uclibc-ng-compile] Error 2
gmake[3]: *** [mk/build.mk:229: toolchain/final] Error 2
gmake[2]: *** [/home/wbx/embedded-test/openadk/mk/build.mk:174: world] Error 2
gmake[1]: *** [Makefile.adk:25: all] Error 2
make: *** [Makefile:22: all] Error 2
build failed
wbx@helium:~/embedded-test$  

Any idea why it fails for me and not for you?
Targeting aarch64 with uClibc-ng master.

best regards
 Waldemar

Marcus Haehnel wrote,

> From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
> 
> While for dynamic linking the _dl_auxvt array is provided in
> dl-startup.c as part of the ldso, is was undefined for statically
> linked binaries. This resulted in a corresponding linker error if
> a statically linked program used getauxval.
> 
> To provide _dl_auxvt also for statically linked binaries, a definition
> of _dl_auxvt is added to dl-support.c and initialized by _dl_aux_init().
> 
> Signed-off-by: Marcus Haehnel <marcus.haehnel@kernkonzept.com>
> ---
>  libc/misc/elf/dl-support.c          | 16 +++++++++++++---
>  libc/misc/internals/__uClibc_main.c | 22 ++++++----------------
>  2 files changed, 19 insertions(+), 19 deletions(-)
> 
> diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
> index 87cd1bb72..81c78fa55 100644
> --- a/libc/misc/elf/dl-support.c
> +++ b/libc/misc/elf/dl-support.c
> @@ -12,6 +12,7 @@
>   */
>  
>  #include <link.h>
> +#include <ldso.h>
>  #include <elf.h>
>  #if defined(USE_TLS) && USE_TLS
>  #include <assert.h>
> @@ -31,17 +32,26 @@ ElfW(Phdr) *_dl_phdr;
>  size_t _dl_phnum;
>  size_t _dl_pagesize;
>  
> +ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
> +
>  void internal_function _dl_aux_init (ElfW(auxv_t) *av);
>  void internal_function _dl_aux_init (ElfW(auxv_t) *av)
>  {
> +   memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt));
> +   for (; av->a_type != AT_NULL; av++)
> +     {
> +       if (av->a_type < AUX_MAX_AT_ID)
> +         _dl_auxvt[av->a_type] = *av;
> +     }
> +
>     /* Get the program headers base address from the aux vect */
> -   _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
> +   _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val;
>  
>     /* Get the number of program headers from the aux vect */
> -   _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val;
> +   _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val;
>  
>     /* Get the pagesize from the aux vect */
> -   _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
> +   _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
>  }
>  
>  #if defined(USE_TLS) && USE_TLS
> diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
> index 64a9c8214..a84492248 100644
> --- a/libc/misc/internals/__uClibc_main.c
> +++ b/libc/misc/internals/__uClibc_main.c
> @@ -43,7 +43,7 @@
>  /* Are we in a secure process environment or are we dealing
>   * with setuid stuff?  If we are dynamically linked, then we
>   * already have _dl_secure, otherwise we need to re-examine
> - * auxvt[] below.
> + * _dl_auxvt[] below.
>   */
>  int _pe_secure = 0;
>  libc_hidden_data_def(_pe_secure)
> @@ -373,7 +373,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
>  {
>  #ifndef SHARED
>      unsigned long *aux_dat;
> -    ElfW(auxv_t) auxvt[AT_EGID + 1];
>  #endif
>  
>  #ifdef __UCLIBC_HAS_THREADS_NATIVE__
> @@ -399,23 +398,14 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
>  
>  #ifndef SHARED
>      /* Pull stuff from the ELF header when possible */
> -    memset(auxvt, 0x00, sizeof(auxvt));
>      aux_dat = (unsigned long*)__environ;
>      while (*aux_dat) {
>  	aux_dat++;
>      }
>      aux_dat++;
> -    while (*aux_dat) {
> -	ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
> -	if (auxv_entry->a_type <= AT_EGID) {
> -	    memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t)));
> -	}
> -	aux_dat += 2;
> -    }
>      /* Get the program headers (_dl_phdr) from the aux vector
>         It will be used into __libc_setup_tls. */
> -
> -    _dl_aux_init (auxvt);
> +    _dl_aux_init ((ElfW(auxv_t) *)aux_dat);
>  #endif
>  
>      /* We need to initialize uClibc.  If we are dynamically linked this
> @@ -431,10 +421,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
>  #ifndef SHARED
>      /* Prevent starting SUID binaries where the stdin. stdout, and
>       * stderr file descriptors are not already opened. */
> -    if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> -	    (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
> -	    (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
> -	     auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
> +    if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> +	    (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
> +	    (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val ||
> +	     _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val)))
>  #else
>      if (_dl_secure)
>  #endif
> -- 
> 2.47.1
> 
> _______________________________________________
> devel mailing list -- devel@uclibc-ng.org
> To unsubscribe send an email to devel-leave@uclibc-ng.org
>
Marcus Haehnel March 6, 2025, 1:41 p.m. UTC | #2
Hi Waldemar,

our apologies. I only compiled this in our environment where the failing code is not used.
We can reproduce the issue and are looking for a fix.

- Marcus

On Thu, 2025-03-06 at 14:08 +0100, Waldemar Brodkorb wrote:
> Hi Marcus,
> 
> I accidentally pushed the changes and now get following build error:
> 
> libc/misc/internals/__uClibc_main.c: In function '__uClibc_main':
> libc/misc/internals/__uClibc_main.c:424:10: error: '_dl_auxvt' undeclared (first use in this function); did you mean '_dl_aux_init'?
>   424 |     if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
>       |          ^~~~~~~~~
>       |          _dl_aux_init
> libc/misc/internals/__uClibc_main.c:424:10: note: each undeclared identifier is reported only once for each function it appears in
> gmake[6]: *** [Makerules:373: libc/misc/internals/__uClibc_main.os] Error 1
> gmake[5]: *** [Makefile:353: /home/wbx/embedded-test/openadk/toolchain_build_qemu-aarch64_uclibc-ng_cortex_a53/w-uClibc-ng-1.0.51-1/uClibc-ng-1.0.51/.compiled] Error 2
> gmake[4]: *** [Makefile:106: uclibc-ng-compile] Error 2
> gmake[3]: *** [mk/build.mk:229: toolchain/final] Error 2
> gmake[2]: *** [/home/wbx/embedded-test/openadk/mk/build.mk:174: world] Error 2
> gmake[1]: *** [Makefile.adk:25: all] Error 2
> make: *** [Makefile:22: all] Error 2
> build failed
> wbx@helium:~/embedded-test$  
> 
> Any idea why it fails for me and not for you?
> Targeting aarch64 with uClibc-ng master.
> 
> best regards
>  Waldemar
> 
> Marcus Haehnel wrote,
> 
> > From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
> > 
> > While for dynamic linking the _dl_auxvt array is provided in
> > dl-startup.c as part of the ldso, is was undefined for statically
> > linked binaries. This resulted in a corresponding linker error if
> > a statically linked program used getauxval.
> > 
> > To provide _dl_auxvt also for statically linked binaries, a definition
> > of _dl_auxvt is added to dl-support.c and initialized by _dl_aux_init().
> > 
> > Signed-off-by: Marcus Haehnel <marcus.haehnel@kernkonzept.com>
> > ---
> >  libc/misc/elf/dl-support.c          | 16 +++++++++++++---
> >  libc/misc/internals/__uClibc_main.c | 22 ++++++----------------
> >  2 files changed, 19 insertions(+), 19 deletions(-)
> > 
> > diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
> > index 87cd1bb72..81c78fa55 100644
> > --- a/libc/misc/elf/dl-support.c
> > +++ b/libc/misc/elf/dl-support.c
> > @@ -12,6 +12,7 @@
> >   */
> >  
> >  #include <link.h>
> > +#include <ldso.h>
> >  #include <elf.h>
> >  #if defined(USE_TLS) && USE_TLS
> >  #include <assert.h>
> > @@ -31,17 +32,26 @@ ElfW(Phdr) *_dl_phdr;
> >  size_t _dl_phnum;
> >  size_t _dl_pagesize;
> >  
> > +ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
> > +
> >  void internal_function _dl_aux_init (ElfW(auxv_t) *av);
> >  void internal_function _dl_aux_init (ElfW(auxv_t) *av)
> >  {
> > +   memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt));
> > +   for (; av->a_type != AT_NULL; av++)
> > +     {
> > +       if (av->a_type < AUX_MAX_AT_ID)
> > +         _dl_auxvt[av->a_type] = *av;
> > +     }
> > +
> >     /* Get the program headers base address from the aux vect */
> > -   _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
> > +   _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val;
> >  
> >     /* Get the number of program headers from the aux vect */
> > -   _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val;
> > +   _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val;
> >  
> >     /* Get the pagesize from the aux vect */
> > -   _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
> > +   _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
> >  }
> >  
> >  #if defined(USE_TLS) && USE_TLS
> > diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
> > index 64a9c8214..a84492248 100644
> > --- a/libc/misc/internals/__uClibc_main.c
> > +++ b/libc/misc/internals/__uClibc_main.c
> > @@ -43,7 +43,7 @@
> >  /* Are we in a secure process environment or are we dealing
> >   * with setuid stuff?  If we are dynamically linked, then we
> >   * already have _dl_secure, otherwise we need to re-examine
> > - * auxvt[] below.
> > + * _dl_auxvt[] below.
> >   */
> >  int _pe_secure = 0;
> >  libc_hidden_data_def(_pe_secure)
> > @@ -373,7 +373,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
> >  {
> >  #ifndef SHARED
> >      unsigned long *aux_dat;
> > -    ElfW(auxv_t) auxvt[AT_EGID + 1];
> >  #endif
> >  
> >  #ifdef __UCLIBC_HAS_THREADS_NATIVE__
> > @@ -399,23 +398,14 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
> >  
> >  #ifndef SHARED
> >      /* Pull stuff from the ELF header when possible */
> > -    memset(auxvt, 0x00, sizeof(auxvt));
> >      aux_dat = (unsigned long*)__environ;
> >      while (*aux_dat) {
> >  	aux_dat++;
> >      }
> >      aux_dat++;
> > -    while (*aux_dat) {
> > -	ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
> > -	if (auxv_entry->a_type <= AT_EGID) {
> > -	    memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t)));
> > -	}
> > -	aux_dat += 2;
> > -    }
> >      /* Get the program headers (_dl_phdr) from the aux vector
> >         It will be used into __libc_setup_tls. */
> > -
> > -    _dl_aux_init (auxvt);
> > +    _dl_aux_init ((ElfW(auxv_t) *)aux_dat);
> >  #endif
> >  
> >      /* We need to initialize uClibc.  If we are dynamically linked this
> > @@ -431,10 +421,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
> >  #ifndef SHARED
> >      /* Prevent starting SUID binaries where the stdin. stdout, and
> >       * stderr file descriptors are not already opened. */
> > -    if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> > -	    (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
> > -	    (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
> > -	     auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
> > +    if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> > +	    (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
> > +	    (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val ||
> > +	     _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val)))
> >  #else
> >      if (_dl_secure)
> >  #endif
> > -- 
> > 2.47.1
> > 
> > _______________________________________________
> > devel mailing list -- devel@uclibc-ng.org
> > To unsubscribe send an email to devel-leave@uclibc-ng.org
> > 
> _______________________________________________
> devel mailing list -- devel@uclibc-ng.org
> To unsubscribe send an email to devel-leave@uclibc-ng.org
Marcus Haehnel March 6, 2025, 2:11 p.m. UTC | #3
I just sent a proposal to fix the issue. This needs a small modification to ldso.h however.

In my opinion the `AUX_MAX_AT_ID` and `_dl_auxvt` definitions are a bit misplaced in that file anyways. An alternative to
the sent patch would be to introduce a new header `dl-auxvt.h` that is included by `ldso.h` and by `__uClibc_main.c`
instead. However, that seems a bit more invasive. If you want I can try the alternative as well and submit an alternate
patch for that version.

Best regards and again apologies for the hassle,

- Marcus



On Thu, 2025-03-06 at 14:41 +0100, Marcus Hähnel wrote:
> Hi Waldemar,
> 
> our apologies. I only compiled this in our environment where the failing code is not used.
> We can reproduce the issue and are looking for a fix.
> 
> - Marcus
> 
> On Thu, 2025-03-06 at 14:08 +0100, Waldemar Brodkorb wrote:
> > Hi Marcus,
> > 
> > I accidentally pushed the changes and now get following build error:
> > 
> > libc/misc/internals/__uClibc_main.c: In function '__uClibc_main':
> > libc/misc/internals/__uClibc_main.c:424:10: error: '_dl_auxvt' undeclared (first use in this function); did you mean '_dl_aux_init'?
> >   424 |     if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> >       |          ^~~~~~~~~
> >       |          _dl_aux_init
> > libc/misc/internals/__uClibc_main.c:424:10: note: each undeclared identifier is reported only once for each function it appears in
> > gmake[6]: *** [Makerules:373: libc/misc/internals/__uClibc_main.os] Error 1
> > gmake[5]: *** [Makefile:353: /home/wbx/embedded-test/openadk/toolchain_build_qemu-aarch64_uclibc-ng_cortex_a53/w-uClibc-ng-1.0.51-1/uClibc-ng-1.0.51/.compiled] Error 2
> > gmake[4]: *** [Makefile:106: uclibc-ng-compile] Error 2
> > gmake[3]: *** [mk/build.mk:229: toolchain/final] Error 2
> > gmake[2]: *** [/home/wbx/embedded-test/openadk/mk/build.mk:174: world] Error 2
> > gmake[1]: *** [Makefile.adk:25: all] Error 2
> > make: *** [Makefile:22: all] Error 2
> > build failed
> > wbx@helium:~/embedded-test$  
> > 
> > Any idea why it fails for me and not for you?
> > Targeting aarch64 with uClibc-ng master.
> > 
> > best regards
> >  Waldemar
> > 
> > Marcus Haehnel wrote,
> > 
> > > From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
> > > 
> > > While for dynamic linking the _dl_auxvt array is provided in
> > > dl-startup.c as part of the ldso, is was undefined for statically
> > > linked binaries. This resulted in a corresponding linker error if
> > > a statically linked program used getauxval.
> > > 
> > > To provide _dl_auxvt also for statically linked binaries, a definition
> > > of _dl_auxvt is added to dl-support.c and initialized by _dl_aux_init().
> > > 
> > > Signed-off-by: Marcus Haehnel <marcus.haehnel@kernkonzept.com>
> > > ---
> > >  libc/misc/elf/dl-support.c          | 16 +++++++++++++---
> > >  libc/misc/internals/__uClibc_main.c | 22 ++++++----------------
> > >  2 files changed, 19 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
> > > index 87cd1bb72..81c78fa55 100644
> > > --- a/libc/misc/elf/dl-support.c
> > > +++ b/libc/misc/elf/dl-support.c
> > > @@ -12,6 +12,7 @@
> > >   */
> > >  
> > >  #include <link.h>
> > > +#include <ldso.h>
> > >  #include <elf.h>
> > >  #if defined(USE_TLS) && USE_TLS
> > >  #include <assert.h>
> > > @@ -31,17 +32,26 @@ ElfW(Phdr) *_dl_phdr;
> > >  size_t _dl_phnum;
> > >  size_t _dl_pagesize;
> > >  
> > > +ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
> > > +
> > >  void internal_function _dl_aux_init (ElfW(auxv_t) *av);
> > >  void internal_function _dl_aux_init (ElfW(auxv_t) *av)
> > >  {
> > > +   memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt));
> > > +   for (; av->a_type != AT_NULL; av++)
> > > +     {
> > > +       if (av->a_type < AUX_MAX_AT_ID)
> > > +         _dl_auxvt[av->a_type] = *av;
> > > +     }
> > > +
> > >     /* Get the program headers base address from the aux vect */
> > > -   _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
> > > +   _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val;
> > >  
> > >     /* Get the number of program headers from the aux vect */
> > > -   _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val;
> > > +   _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val;
> > >  
> > >     /* Get the pagesize from the aux vect */
> > > -   _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
> > > +   _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
> > >  }
> > >  
> > >  #if defined(USE_TLS) && USE_TLS
> > > diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
> > > index 64a9c8214..a84492248 100644
> > > --- a/libc/misc/internals/__uClibc_main.c
> > > +++ b/libc/misc/internals/__uClibc_main.c
> > > @@ -43,7 +43,7 @@
> > >  /* Are we in a secure process environment or are we dealing
> > >   * with setuid stuff?  If we are dynamically linked, then we
> > >   * already have _dl_secure, otherwise we need to re-examine
> > > - * auxvt[] below.
> > > + * _dl_auxvt[] below.
> > >   */
> > >  int _pe_secure = 0;
> > >  libc_hidden_data_def(_pe_secure)
> > > @@ -373,7 +373,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
> > >  {
> > >  #ifndef SHARED
> > >      unsigned long *aux_dat;
> > > -    ElfW(auxv_t) auxvt[AT_EGID + 1];
> > >  #endif
> > >  
> > >  #ifdef __UCLIBC_HAS_THREADS_NATIVE__
> > > @@ -399,23 +398,14 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
> > >  
> > >  #ifndef SHARED
> > >      /* Pull stuff from the ELF header when possible */
> > > -    memset(auxvt, 0x00, sizeof(auxvt));
> > >      aux_dat = (unsigned long*)__environ;
> > >      while (*aux_dat) {
> > >  	aux_dat++;
> > >      }
> > >      aux_dat++;
> > > -    while (*aux_dat) {
> > > -	ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
> > > -	if (auxv_entry->a_type <= AT_EGID) {
> > > -	    memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t)));
> > > -	}
> > > -	aux_dat += 2;
> > > -    }
> > >      /* Get the program headers (_dl_phdr) from the aux vector
> > >         It will be used into __libc_setup_tls. */
> > > -
> > > -    _dl_aux_init (auxvt);
> > > +    _dl_aux_init ((ElfW(auxv_t) *)aux_dat);
> > >  #endif
> > >  
> > >      /* We need to initialize uClibc.  If we are dynamically linked this
> > > @@ -431,10 +421,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
> > >  #ifndef SHARED
> > >      /* Prevent starting SUID binaries where the stdin. stdout, and
> > >       * stderr file descriptors are not already opened. */
> > > -    if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> > > -	    (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
> > > -	    (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
> > > -	     auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
> > > +    if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
> > > +	    (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
> > > +	    (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val ||
> > > +	     _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val)))
> > >  #else
> > >      if (_dl_secure)
> > >  #endif
> > > -- 
> > > 2.47.1
> > > 
> > > _______________________________________________
> > > devel mailing list -- devel@uclibc-ng.org
> > > To unsubscribe send an email to devel-leave@uclibc-ng.org
> > > 
> > _______________________________________________
> > devel mailing list -- devel@uclibc-ng.org
> > To unsubscribe send an email to devel-leave@uclibc-ng.org
>
Waldemar Brodkorb March 6, 2025, 3:44 p.m. UTC | #4
Hi Marcus,
Marcus Hähnel wrote,

> I just sent a proposal to fix the issue. This needs a small modification to ldso.h however.
> 
> In my opinion the `AUX_MAX_AT_ID` and `_dl_auxvt` definitions are a bit misplaced in that file anyways. An alternative to
> the sent patch would be to introduce a new header `dl-auxvt.h` that is included by `ldso.h` and by `__uClibc_main.c`
> instead. However, that seems a bit more invasive. If you want I can try the alternative as well and submit an alternate
> patch for that version.

I pushed your hotfix, but would also like to include any follow up
cleanup patch.

best regards
 Waldemar
Marcus Haehnel March 7, 2025, 7:16 a.m. UTC | #5
Thanks Waldemar,

I sent another patch that I would say is a cleaner solution since it separates the _dl_auxvt logic, which is needed in
static and shared builds due to getauxval, from the ldso specific things.

But I'm not sure if you have any policy regarding the addition of new headers, or if I am missing something. So I would
welcome any feedback.

Best regards,

- Marcus

On Thu, 2025-03-06 at 16:44 +0100, Waldemar Brodkorb wrote:
> Hi Marcus,
> Marcus Hähnel wrote,
> 
> > I just sent a proposal to fix the issue. This needs a small modification to ldso.h however.
> > 
> > In my opinion the `AUX_MAX_AT_ID` and `_dl_auxvt` definitions are a bit misplaced in that file anyways. An alternative to
> > the sent patch would be to introduce a new header `dl-auxvt.h` that is included by `ldso.h` and by `__uClibc_main.c`
> > instead. However, that seems a bit more invasive. If you want I can try the alternative as well and submit an alternate
> > patch for that version.
> 
> I pushed your hotfix, but would also like to include any follow up
> cleanup patch.
> 
> best regards
>  Waldemar
> _______________________________________________
> devel mailing list -- devel@uclibc-ng.org
> To unsubscribe send an email to devel-leave@uclibc-ng.org
diff mbox series

Patch

diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
index 87cd1bb72..81c78fa55 100644
--- a/libc/misc/elf/dl-support.c
+++ b/libc/misc/elf/dl-support.c
@@ -12,6 +12,7 @@ 
  */
 
 #include <link.h>
+#include <ldso.h>
 #include <elf.h>
 #if defined(USE_TLS) && USE_TLS
 #include <assert.h>
@@ -31,17 +32,26 @@  ElfW(Phdr) *_dl_phdr;
 size_t _dl_phnum;
 size_t _dl_pagesize;
 
+ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
+
 void internal_function _dl_aux_init (ElfW(auxv_t) *av);
 void internal_function _dl_aux_init (ElfW(auxv_t) *av)
 {
+   memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt));
+   for (; av->a_type != AT_NULL; av++)
+     {
+       if (av->a_type < AUX_MAX_AT_ID)
+         _dl_auxvt[av->a_type] = *av;
+     }
+
    /* Get the program headers base address from the aux vect */
-   _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
+   _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val;
 
    /* Get the number of program headers from the aux vect */
-   _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val;
+   _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val;
 
    /* Get the pagesize from the aux vect */
-   _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
+   _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
 }
 
 #if defined(USE_TLS) && USE_TLS
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 64a9c8214..a84492248 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -43,7 +43,7 @@ 
 /* Are we in a secure process environment or are we dealing
  * with setuid stuff?  If we are dynamically linked, then we
  * already have _dl_secure, otherwise we need to re-examine
- * auxvt[] below.
+ * _dl_auxvt[] below.
  */
 int _pe_secure = 0;
 libc_hidden_data_def(_pe_secure)
@@ -373,7 +373,6 @@  void __uClibc_main(int (*main)(int, char **, char **), int argc,
 {
 #ifndef SHARED
     unsigned long *aux_dat;
-    ElfW(auxv_t) auxvt[AT_EGID + 1];
 #endif
 
 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
@@ -399,23 +398,14 @@  void __uClibc_main(int (*main)(int, char **, char **), int argc,
 
 #ifndef SHARED
     /* Pull stuff from the ELF header when possible */
-    memset(auxvt, 0x00, sizeof(auxvt));
     aux_dat = (unsigned long*)__environ;
     while (*aux_dat) {
 	aux_dat++;
     }
     aux_dat++;
-    while (*aux_dat) {
-	ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
-	if (auxv_entry->a_type <= AT_EGID) {
-	    memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t)));
-	}
-	aux_dat += 2;
-    }
     /* Get the program headers (_dl_phdr) from the aux vector
        It will be used into __libc_setup_tls. */
-
-    _dl_aux_init (auxvt);
+    _dl_aux_init ((ElfW(auxv_t) *)aux_dat);
 #endif
 
     /* We need to initialize uClibc.  If we are dynamically linked this
@@ -431,10 +421,10 @@  void __uClibc_main(int (*main)(int, char **, char **), int argc,
 #ifndef SHARED
     /* Prevent starting SUID binaries where the stdin. stdout, and
      * stderr file descriptors are not already opened. */
-    if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
-	    (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
-	    (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val ||
-	     auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val)))
+    if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) ||
+	    (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
+	    (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val ||
+	     _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val)))
 #else
     if (_dl_secure)
 #endif