mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] musl attribute constructor does not pass argc and argv as expected?
@ 2020-07-15  0:32 Simon
  2020-07-15  2:34 ` Rich Felker
  0 siblings, 1 reply; 2+ messages in thread
From: Simon @ 2020-07-15  0:32 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1695 bytes --]

Hello!

I tried compiling the test.c snippet here [1] with glibc and musl under
Alpine 3.12 and get the following results:

$ gcc -std=c99 -o test test.c # glibc
$ ldd ./test
        linux-vdso.so.1 (0x00007ffd0bfc9000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd1e9363000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd1e9572000)
$ ./test arg1 arg2
stuff: argv[0] = './test'
stuff: argv[1] = 'arg1'
stuff: argv[2] = 'arg2'
main: argv[0] = './test'
main: argv[1] = 'arg1'
main: argv[2] = 'arg2'

$ gcc -static -std=c99 -o test test.c # musl
$ ldd ./test
        statically linked
$ ./test arg1 arg2
Segmentation fault (core dumped)
$ ./test arg1 arg2
main: argv[0] = './test'
main: argv[1] = 'arg1'
main: argv[2] = 'arg2'

Very infrequently when I run the musl compiled code then I get the seg
fault. And the rest of the time only main() is run.

If I compile without static then same thing:

$ gcc -std=c99 -o test test.c # musl
$ ldd ./test
        linux-vdso.so.1 (0x00007ffed4193000)
        libc.musl-x86_64.so.1 => not found
$ ./test arg1 arg2
main: argv[0] = './test'
main: argv[1] = 'arg1'
main: argv[2] = 'arg2'
$ ./test arg1 arg2
Segmentation fault (core dumped)

If I add the following line of code both functions and recompile with musl
under Alpine:

    printf("- argc=%d\n", argc);

Then the it seems that argc is being passed but the wrong value:

$ ./test arg1 arg2
- argc=-1988853488
- argc=3
main: argv[0] = './test'
main: argv[1] = 'arg1'
main: argv[2] = 'arg2'
$ ./test arg1 arg2
- argc=1409286416
Segmentation fault (core dumped)

Seems like a bug in musl, or what am I doing wrong?

Thanks in advance!

[1] https://stackoverflow.com/a/37012337/1547069

[-- Attachment #2: Type: text/html, Size: 2442 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [musl] musl attribute constructor does not pass argc and argv as expected?
  2020-07-15  0:32 [musl] musl attribute constructor does not pass argc and argv as expected? Simon
@ 2020-07-15  2:34 ` Rich Felker
  0 siblings, 0 replies; 2+ messages in thread
From: Rich Felker @ 2020-07-15  2:34 UTC (permalink / raw)
  To: Simon; +Cc: musl

On Tue, Jul 14, 2020 at 05:32:42PM -0700, Simon wrote:
> Hello!
> 
> I tried compiling the test.c snippet here [1] with glibc and musl under
> Alpine 3.12 and get the following results:
> 
> $ gcc -std=c99 -o test test.c # glibc
> $ ldd ./test
>         linux-vdso.so.1 (0x00007ffd0bfc9000)
>         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd1e9363000)
>         /lib64/ld-linux-x86-64.so.2 (0x00007fd1e9572000)
> $ ./test arg1 arg2
> stuff: argv[0] = './test'
> stuff: argv[1] = 'arg1'
> stuff: argv[2] = 'arg2'
> main: argv[0] = './test'
> main: argv[1] = 'arg1'
> main: argv[2] = 'arg2'
> 
> $ gcc -static -std=c99 -o test test.c # musl
> $ ldd ./test
>         statically linked
> $ ./test arg1 arg2
> Segmentation fault (core dumped)
> $ ./test arg1 arg2
> main: argv[0] = './test'
> main: argv[1] = 'arg1'
> main: argv[2] = 'arg2'
> 
> Very infrequently when I run the musl compiled code then I get the seg
> fault. And the rest of the time only main() is run.
> 
> If I compile without static then same thing:
> 
> $ gcc -std=c99 -o test test.c # musl
> $ ldd ./test
>         linux-vdso.so.1 (0x00007ffed4193000)
>         libc.musl-x86_64.so.1 => not found
> $ ./test arg1 arg2
> main: argv[0] = './test'
> main: argv[1] = 'arg1'
> main: argv[2] = 'arg2'
> $ ./test arg1 arg2
> Segmentation fault (core dumped)
> 
> If I add the following line of code both functions and recompile with musl
> under Alpine:
> 
>     printf("- argc=%d\n", argc);
> 
> Then the it seems that argc is being passed but the wrong value:
> 
> $ ./test arg1 arg2
> - argc=-1988853488
> - argc=3
> main: argv[0] = './test'
> main: argv[1] = 'arg1'
> main: argv[2] = 'arg2'
> $ ./test arg1 arg2
> - argc=1409286416
> Segmentation fault (core dumped)
> 
> Seems like a bug in musl, or what am I doing wrong?
> 
> Thanks in advance!

This is intentional. Relying on the glibc-specific behavior here is
not portable. The ELF spec does not define arguments being passed to
init_array functions, and other (non-glibc) implementations don't do
it either.

Aside from trying to discourage nonportable things (musl was pretty
aggressive about this early on, a bit less so now), this particular
behavior is one where failing hard seems to have been a better choice.
The main case we found of software trying to use the ctor arguments
was in an attempt to relocate argv/environ prior to program entry in
order to make space to do a "setproctitle" operation. This is highly
unsafe, as the dynamic linker and/or __libc_start_main entry-point
code have already saved pointers to some things found there, and will
break in subtle but potentially dangerous ways that might not be
noticed until long after deployment. Crashing immediately in the ctor
trying to poke at them, on the other hand, caused the bad code to be
found and fixed.

> [1] https://stackoverflow.com/a/37012337/1547069

BTW the comments on that answer noted this is not guaranteed at all
and musl doesn't do it.

Rich

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-07-15  2:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-15  0:32 [musl] musl attribute constructor does not pass argc and argv as expected? Simon
2020-07-15  2:34 ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

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 NNTP newsgroup(s).