public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: Farid Zakaria <fmzakari@ucsc.edu>
Cc: Libc-help <libc-help@sourceware.org>
Subject: Re: How can I wrap ld-linux or execve into it?
Date: Tue, 1 Feb 2022 14:49:05 -0300	[thread overview]
Message-ID: <dc6e8632-9003-659d-de1a-5706b32a75f1@linaro.org> (raw)
In-Reply-To: <CAH4OOv4twuJtgy-rD-iwWH0orDmXKTJgq7BRHZQtiq8v5Bq23w@mail.gmail.com>



On 01/02/2022 14:14, Farid Zakaria wrote:
> Thank you -- I need to parse your solution more in depth.
> I will also take a look more at rtld -- however I was hoping to be
> compatible with musl as well.
> 
> I was told by a colleague that execve solution may work if the static
> binary has "no relocations".
> How can I control that through the compilation of a program beyond
> limiting myself to a single object-file?

Different than musl that packs everything in libc.so, glibc still has a 
contract between ld.so and libc.so, where the loader will setup multiple 
global resources where some will be shared between ld.so and libc.so.  
One of the is the thread pointer (TP), required and defined by ABI (for 
all supported architectures).  

So it should be possible to chain execution using this loader like program,
this loader-like program will need to setup the expect machine state for the 
loader's entrypoint (ElfW(Ehdr).e_entry): argc, argv, env, and auxv (you might
also check if some ABI also requires some other state I am forgetting here).
It also means that it would *very* trick to call back the loader as glibc
libc.so does for ld.so on, on for instance, symbol resolution (since TP and
other global states can no be shared).  

It really depends of what you want to perform before dynamic linker. The
"no relocations" I take it means no dynamic relocations, but this is not
suffice (as indicate by the global resource setup required by libc, such
as TP).

I think it would be easier to use a a minimal Linux support without any
libc or standard libraries (similar to a bare-metal target).  I think
you might accomplish it with newlib, but I am not sure.  

> 
> On Tue, Feb 1, 2022 at 4:43 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 31/01/2022 17:10, Farid Zakaria via Libc-help wrote:
>>> Hi,
>>>
>>> I am looking to perform some functionality before the dynamic linker
>>> (linux-ld/ld.so) is invoked.
>>>
>>> My naive assessment was that I would be able to set in the PT_INTERP
>>> section of a binary, my *static binary*, which will then execve into
>>> the dynamic linker after doing some precanned actions.
>>>
>>> Unfortunately, trying this has resulted in some SIGSEGV...
>>>
>>> I came across https://github.com/Mic92/nix-ld which seems to do
>>> something similar, but I was curious why it has to do a lot more to
>>> achieve the same effect with a jump.
>>>
>>> I have also been pointed to LD_AUDIT however I am also interested in
>>> having it agnostic to libc (glibc vs. musl)
>>>
>>> Thank you for any tips, guidance or links you can provide.
>>> FZ
>>
>> The issue is for static linking _dl_aux_init will setup the _dl_phdr
>> to the loaded binary (since it was done by the kernel) passed on auxiliary
>> vectors:
>>
>> elf/dl-support.c:
>>
>> 246 void
>> 247 _dl_aux_init (ElfW(auxv_t) *av)
>> 248 {
>> [...]
>> 269       case AT_PHDR:
>> 270         GL(dl_phdr) = (const void *) av->a_un.a_val;
>> 271         break;
>> [...]
>>
>> And this is later used to setup the TCB:
>>
>> csu/libc-tls.c
>>
>> 104 void
>> 105 __libc_setup_tls (void)
>> 106 {
>> [...]
>> 120   /* Look through the TLS segment if there is any.  */
>> 121   if (_dl_phdr != NULL)
>> 122     for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
>> 123       if (phdr->p_type == PT_TLS)
>> 124         {
>> 125           /* Remember the values we need.  */
>> 126           memsz = phdr->p_memsz;
>> 127           filesz = phdr->p_filesz;
>> 128           initimage = (void *) phdr->p_vaddr + main_map->l_addr;
>> 129           align = phdr->p_align;
>> 130           if (phdr->p_align > max_align)
>> 131             max_align = phdr->p_align;
>> 132           break;
>> 133         }
>>
>> The problem is seice _dl_phdr is not pointing to the static programs acting
>> as loader, the PT_TLS is not considered and thus not initialized correctly.
>> That's why once __ctype_init tries to access TLS variables it triggers an
>> invalid memory reference:
>>
>> (gdb) c
>> Continuing.
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x000000000045f464 in __ctype_init () at ctype-info.c:31
>> 31        *bp = (const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128;
>>
>>
>> And I don't think this would be easy to support without changing a *lot*
>> on static linking organization.  If you check the loader code, it avoids
>> to use TLS exactly to avoid this initialization issue.
>>
>> I think the best option to work by checking elt/rtld.c and see if you can
>> hack a way link you code after its initialization.

      reply	other threads:[~2022-02-01 17:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-31 20:10 Farid Zakaria
2022-01-31 20:29 ` Farid Zakaria
2022-02-01 12:43 ` Adhemerval Zanella
2022-02-01 17:14   ` Farid Zakaria
2022-02-01 17:49     ` Adhemerval Zanella [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dc6e8632-9003-659d-de1a-5706b32a75f1@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=fmzakari@ucsc.edu \
    --cc=libc-help@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).