Folks,
we have seen some issues recently in uClibc related to the way the aux vect is managed inside __uClibc_main.

Running a set-[user,group]-ID ELF binaries with some 'unsecure' environment variable set (i.e LD_LIBRARY_PATH or LD_PRELOAD), auxvt is wrongly set in __uClibc_main.

The problem is caused by the call to _dl_unsetenv function in ldso.c that pops the specific env variables from the stack adding a corresponding number of NULL entries at the end of the environments stack. To be clearer, at the beginning the stack looks like as expected (assuming M env variables and N aux_vect entries)

argc
argv[0]
...
argv[argc-1]
NULL /* separator */
envp[0]
...
LD_LIBRARY_PATH
...
envp[M-1]
NULL /* separator */
aux_vect[0]
.......
aux_vect[N-1]
NULL /* separator */

After the LD_LIBRARY_PATH has been removed by _dl_unsetenv, the stack will look like to libc

argc
argv[0]
...
argv[argc-1]
NULL /* separator */
envp[0]
...
envp[M-2]
NULL /* filled by ld.so */
NULL /* separator */
auxvect[0]
.......
aux_vect[N-1]
NULL /* separator */

Currently, __uClibc_main assumes that there is just one NULL separator between environments and aux_vect entries, as from the extract below:

    aux_dat = (unsigned long*)__environ;
    while (*aux_dat) {
        aux_dat++;
    }
aux_dat++; <-- This move the aux_dat of just 1 position to skip the NULL separator

Due to this, the local auxvt array (initialised by memset) won't be filled with proper values.
All the following code that use the auxvt variable is wrong.

For example, the check for the SUID binaries will be affected, as it needs to verify AT_UID, AT_GID, AT-EUID and AT_EGID entries (all NULL)

A potential dirty fix or work-around would be to replace "aux_dat++" statement with "while (!(*aux_dat++))" to skip all the NULL entries, but doing so there is no way to detect the case where aux_vect is not present.

So, the proper fix we have in mind is to completely remove the aux vect handling from libc and keep it solely into the dynamic linker (as actually glibc is doing). If libc needs to check some values from aux vect, it can refer to globals exported by the ld.so.

Feedback are really welcome,
Regards,
Filippo
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to