Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240723224657.GT10433@brightrain.aerifal.cx>
Date: Tue, 23 Jul 2024 18:46:57 -0400
From: Rich Felker <dalias@...c.org>
To: Alex Rønne Petersen <alex@...xrp.com>
Cc: musl@...ts.openwall.com
Subject: Re: Stack pointer is misaligned when invoking the musl
 dynamic linker directly to run a program without start files

On Tue, Jul 23, 2024 at 11:42:51PM +0200, Alex Rønne Petersen wrote:
> Hi,
> 
> Repro:
> 
>     $ cat test.s
>     .global _start
>     _start:
>     mov %rsp, %rdi
>     and $15, %rdi
>     call exit
>     $ musl-gcc test.s -nostartfiles
>     $ ./a.out; echo $?
>     0
>     $ /lib64/ld-linux-x86-64.so.2 ./a.out; echo $?
>     0
>     $ /lib/ld-musl-x86_64.so.1 ./a.out; echo $?
>     8
>     $ /lib/ld-musl-x86_64.so.1 --version
>     musl libc (x86_64)
>     Version 1.2.3
> 
> I could well be missing something here, but at first glance, this
> *seems* like an ABI violation; the x86-64 psABI [0] states in §3.4.1
> that RSP is guaranteed to be 16-byte aligned on process entry. The
> same is true of many other architectures (though the amount obviously
> differs).
> 
> I suppose it's debatable whether a program interpreter ought to be
> required to uphold the same guarantees as the kernel on process
> initialization?
> 
> [0] https://gitlab.com/x86-psABIs/x86-64-ABI

This is intentional. _start is not a C function subject to psABI
calling convention. It's an entry point with its own convention that
the stack pointer register point at the start of the ELF argument
packing, and that has a requirement to align the stack before calling
into C code.

This is something we could change if there were some strong motivation
to, with some memmove. But I think that's unlikely. There is no
externally imposed public programming interface contract we're trying
to match here.

FWIW the above program is invalid by virtue of calling exit without
the program having been entered via __libc_start_main. Critical state
needed for any libc function, including exit, to work may be
uninitialized. To make it valid you'd need to hard-code the
SYS_exit_group syscall in asm or pass execution through
__libc_start_main.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.