From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 4127 invoked from network); 15 Jul 2020 02:34:51 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 15 Jul 2020 02:34:51 -0000 Received: (qmail 32091 invoked by uid 550); 15 Jul 2020 02:34:45 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 32070 invoked from network); 15 Jul 2020 02:34:44 -0000 Date: Tue, 14 Jul 2020 22:34:32 -0400 From: Rich Felker To: Simon Cc: musl@lists.openwall.com Message-ID: <20200715023432.GC14669@brightrain.aerifal.cx> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] musl attribute constructor does not pass argc and argv as expected? 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