[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 5/5] add setting gs/fsbase

From: Sergey Bugaev
Subject: Re: [PATCH 5/5] add setting gs/fsbase
Date: Thu, 20 Apr 2023 14:51:04 +0300

On Wed, Apr 19, 2023 at 11:52 PM Sergey Bugaev <bugaevc@gmail.com> wrote:
> On Wed, Apr 19, 2023 at 10:48 PM Luca Dariz <luca@orpolo.org> wrote:
> > * i386/i386/pcb.c: switch FSBASE/GSBASE on context switch and
> >   implement accessors in thread setstatus/getstatus
> > * i386/i386/thread.h: add new state to thread saved state
> > * kern/thread.c: add i386_FSGS_BASE_STATE handler
> Hi Luca -- this is great!
> I will build gnumach with your changes and see if that works with my
> latest build of x86_64-gnu glibc.

Well, too bad -- as is, we don't even get to actually doing the
thread_set_state () RPC.

We do reach the call to __thread_set_state (), but then it uses
__mig_memcpy (), which is just 'return memcpy (...)'. And (because of
the static build?), that memcpy () is the full real ifunc-selected
memcpy. So it jumps to the memcpy@plt, which jumps to
*(memcpy@got.plt), which is supposed to jump into the rtld and then
run the ifunc resolver and do its smarts and eventually jump to the
right memcpy...

But of course none of that is happening because we haven't really
started running any of rtld proper yet, we're still inside
_hurd_stack_setup (). So there was no-one to apply the relocations to
our .got.plt yet, and they point to who knows where. (In practice,
back to the PLT.)

Why had this worked for me when I was running it on Linux? Most likely
I have skipped over the whole __thread_set_state () call and not just
the 'syscall'. Why was this not an issue for us on i386? Two reasons:

* i386_set_gdt () doesn't need memcpy;
* memcpy is not ifunc-resolved in static i386

We can't run libc_start_main () (which is what calls
ARCH_INIT_CPU_FEATURES and then _dl_relocate_static_pie) before we
get our argv/envp and our new stack, but to do that we need MIG, and
MIG will memcpy...

So how do we get out of this chicken-and-egg situation? Well, like
this of course:

leaq __memcpy_sse2_unaligned(%rip), %rax
movq %rax, memcpy@GOTPCREL(%rip)

Call that either a terrible hack or a brilliant solution :) :) :)
and I'm sure H.J. Lu over on libc-alpha will appreciate it when I
send the patch. But -- it works! I can get through memcpy now, and
__thread_set_state () succeeds and writes $fs_base as seen from GDB!
So, great work on this!

Now, this exposed some of my own bugs in glibc... and after quickly
fixing them, I'm now stuck at trying to allocate memory. Specifically,
I'd like to have memory at 0x200000000000 and some further, but
gnumach is not letting me! -- because that's more than
VM_MAX_USER_ADDRESS, which is defined to VM_MAX_ADDRESS, which is then
defined to 0xc0000000, same as on i386. That's of course too small.
Can we bump this substantially?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]