Message ID | 20220816203400.161187-4-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | accel/tcg + target/arm: pc-relative translation | expand |
On Tue, 2022-08-16 at 15:33 -0500, Richard Henderson wrote: > We're about to start validating PAGE_EXEC, which means that we've > got to the vsyscall page executable. We had been special casing > this entirely within translate. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/elfload.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index 29d910c4cc..d783240a36 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -195,6 +195,28 @@ static void > elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en > (*regs)[26] = tswapreg(env->segs[R_GS].selector & 0xffff); > } > > +#if ULONG_MAX >= TARGET_VSYSCALL_PAGE > +#define HI_COMMPAGE TARGET_VSYSCALL_PAGE > + > +static bool init_guest_commpage(void) > +{ > + /* > + * The vsyscall page is at a high negative address aka kernel > space, > + * which means that we cannot actually allocate it with > target_mmap. > + * We still should be able to use page_set_flags, unless the > user > + * has specified -R reserved_va, which would trigger an > assert(). > + */ > + if (reserved_va != 0 && > + TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE >= reserved_va) { > + error_report("Cannot allocate vsyscall page"); > + exit(EXIT_FAILURE); > + } > + page_set_flags(TARGET_VSYSCALL_PAGE, > + TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE, > + PAGE_EXEC | PAGE_VALID); > + return true; > +} > +#endif > #else > > #define ELF_START_MMAP 0x80000000 I found this in context of wasmtime, but apparently the problem is more broad: after this patch any x86_64 PIE binaries no longer run: qemu-x86_64: ../linux-user/elfload.c:2657: pgb_dynamic: Assertion `sizeof(uintptr_t) == 4' failed. Aborted (core dumped) (Maybe we need a test for this, PIE version of "hello world" will do.) I wonder if we need this assert at all? There is a comment that says that 64-bit hosts should have used reserved_va, but what is the reasoning behind this restriction? Without this assert, pgb_find_hole() finds a suitable hole just fine.
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 29d910c4cc..d783240a36 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -195,6 +195,28 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en (*regs)[26] = tswapreg(env->segs[R_GS].selector & 0xffff); } +#if ULONG_MAX >= TARGET_VSYSCALL_PAGE +#define HI_COMMPAGE TARGET_VSYSCALL_PAGE + +static bool init_guest_commpage(void) +{ + /* + * The vsyscall page is at a high negative address aka kernel space, + * which means that we cannot actually allocate it with target_mmap. + * We still should be able to use page_set_flags, unless the user + * has specified -R reserved_va, which would trigger an assert(). + */ + if (reserved_va != 0 && + TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE >= reserved_va) { + error_report("Cannot allocate vsyscall page"); + exit(EXIT_FAILURE); + } + page_set_flags(TARGET_VSYSCALL_PAGE, + TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE, + PAGE_EXEC | PAGE_VALID); + return true; +} +#endif #else #define ELF_START_MMAP 0x80000000
We're about to start validating PAGE_EXEC, which means that we've got to the vsyscall page executable. We had been special casing this entirely within translate. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/elfload.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)