From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13468 Path: news.gmane.org!.POSTED!not-for-mail From: Gernot Reisinger Newsgroups: gmane.linux.lib.musl.general Subject: Re: Question regarding dynamic loader Date: Wed, 21 Nov 2018 16:52:53 +0100 Message-ID: References: <20181121142550.GA23599@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000746be2057b2ec057" X-Trace: blaine.gmane.org 1542815844 15496 195.159.176.226 (21 Nov 2018 15:57:24 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 21 Nov 2018 15:57:24 +0000 (UTC) Cc: musl@lists.openwall.com To: dalias@libc.org Original-X-From: musl-return-13484-gllmg-musl=m.gmane.org@lists.openwall.com Wed Nov 21 16:57:20 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1gPUsS-0003ts-4b for gllmg-musl@m.gmane.org; Wed, 21 Nov 2018 16:57:20 +0100 Original-Received: (qmail 29937 invoked by uid 550); 21 Nov 2018 15:59:29 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 24215 invoked from network); 21 Nov 2018 15:53:42 -0000 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=MP1bJZZzucEmdeBqFEEdWVochlVn5RGCQh6psHwtBjE=; b=NbYMoqXSImootqpUYpIa7Jued813LsejGwcExmoNdavrV2cPeO38IcRfVNlM55+t/s aYpTyFXLiudG6vZ9OM8fw0MisFjm4AS506jK4qJNv9cZq0F8Kx8XBUpYGJcXwK+j9Vaf v+0PCp508ZPH/YT+6Mlf3rXEQY1s8n7SBY2JsUt7yp6MdehkeKB78z32mdu4lvqcOYRb TlJgJBzW+I6elvurlZSQC9FzsEBnPItFgq+tkREBNRrSXHLArGH0eEQLJtHQ20P885gc Yqlvh7ZiyDxNWJiqhPm4F5ah9ZsJQpsVgTabTXONR8xJhjex9ncDalmMjkZkWMPcEOmn hIoQ== X-Gm-Message-State: AA+aEWZm3leIFvU6a65sOfdGVcraeobFbcFRUazBcmDBi7mqULqyeP// VifYjRanw7SBxLetINumznM9uSimI4yaJY1BFabWyvCe X-Google-Smtp-Source: AFSGD/WuuYheMaD/CuSKDpz6XqP9C2RfXxoPzLHGXd3w9WmQlNpnYDkUDkJtB3EO6M2vmAnEuWxnplfkoSoQHsV9ybs= X-Received: by 2002:a2e:9bc3:: with SMTP id w3-v6mr4286565ljj.70.1542815611119; Wed, 21 Nov 2018 07:53:31 -0800 (PST) In-Reply-To: <20181121142550.GA23599@brightrain.aerifal.cx> Xref: news.gmane.org gmane.linux.lib.musl.general:13468 Archived-At: --000000000000746be2057b2ec057 Content-Type: text/plain; charset="UTF-8" Thanks for your swift and extensive reply. Your explanations make a lot of sense. (sorry for my sloppy description - __libc_start_main invoked by *crt is the place where constructor calls happen as you did outline). I did no extensive research how glibc executes these constructor calls. At least the call stack indicates that they are partially executed in dynamic linker context - _dl_start_user () in /lib64/ld-linux-x86-64.so calling _dl_init. I will add a reference to reply to the Go ticket. Am Mi., 21. Nov. 2018 um 15:25 Uhr schrieb Rich Felker : > On Wed, Nov 21, 2018 at 02:55:19PM +0100, Gernot Reisinger wrote: > > Hi, > > I recently stumbled upon an issue with preloading a shared object into a > Go > > application (see related Go ticket > https://github.com/golang/go/issues/28909 > > ). > > > > In short - Go comes with an internal linker which will not link crt code > to > > the application. The entry point will directly execute Go standard > library > > code. As musl libc calls shared object constructors in crt code, the > shared > > I don't think this assessment of what musl does is correct. It calls > the (initially loaded) shared object constructor via > __libc_start_main. If the program is not entered via > __libc_start_main, libc is not usable. Necessary initialization will > have been bypassed. This has little to do with whether the crt code > was linked, except that *crt1.o is normally responsible for calling > __libc_start_main. If the linking process bypasses crt1, it needs to > ensure that __libc_start_main ends up getting called in some other > way. As far as I know this is also true for glibc, so I'm not sure why > it differs. > > > objects constructors subsequently will never be invoked. Things will work > > on glibc systems / processes. it It seems to be a subtle - but in this > case > > wide reaching - behavioral difference to glibc. > > > > I wonder if calling constructor functions from crt code is an intended > musl > > libc behavior. My personal - non expert - gut feeling considers glibc > > behavior "more correct". Is there a chance that musl will change this > > behavior? > > The musl behavior here is intentional. For FDPIC targets, it's > impossible to run *any* application code, in the main application or > shared libraries, before the main application's crt1 has executed, > because there are (essentially -- the equivalent of) self-relocations > performed at that stage that the dynamic linker can't see. If any > ctors were invoked directly by the dynamic linker before passing > control the the main application's entry point, they would run without > these relocations in the main application having been performed, > possibly resulting in runaway-wrong execution. > > I believe Go is doing some bad hacks here with regard to its C FFI, > but it's likely fixable in some reasonable way. We should get more > eyes looking at it. > > Rich > > --000000000000746be2057b2ec057 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks for your swi= ft and extensive reply. Your explanations make a lot of sense. (sorry for m= y sloppy description - __libc_start_main invoked by *crt is the place where= constructor calls happen as you did outline).
I did no extensive= research how glibc executes these constructor calls. At least the call sta= ck indicates that they are partially executed in dynamic linker context - _= dl_start_user () in /lib64/ld-linux-x86-64.so calling=C2=A0_dl_init.

I will add a reference to reply to the Go ticket.=C2= =A0

= Am Mi., 21. Nov. 2018 um 15:25=C2=A0Uhr schrieb Rich Felker <dalias@libc.org>:
On Wed, Nov 21, 2018 at 02:55:19PM +0100, G= ernot Reisinger wrote:
> Hi,
> I recently stumbled upon an issue with preloading a shared object into= a Go
> application (see related Go ticket https://github.com/= golang/go/issues/28909
> ).
>
> In short - Go comes with an internal linker which will not link crt co= de to
> the application. The entry point will directly execute Go standard lib= rary
> code. As musl libc calls shared object constructors in crt code, the s= hared

I don't think this assessment of what musl does is correct. It calls the (initially loaded) shared object constructor via
__libc_start_main. If the program is not entered via
__libc_start_main, libc is not usable. Necessary initialization will
have been bypassed. This has little to do with whether the crt code
was linked, except that *crt1.o is normally responsible for calling
__libc_start_main. If the linking process bypasses crt1, it needs to
ensure that __libc_start_main ends up getting called in some other
way. As far as I know this is also true for glibc, so I'm not sure why<= br> it differs.

> objects constructors subsequently will never be invoked. Things will w= ork
> on glibc systems / processes. it It seems to be a subtle - but in this= case
> wide reaching - behavioral difference to glibc.
>
> I wonder if calling constructor functions from crt code is an intended= musl
> libc behavior. My personal - non expert - gut feeling considers glibc<= br> > behavior "more correct". Is there a chance that musl will ch= ange this
> behavior?

The musl behavior here is intentional. For FDPIC targets, it's
impossible to run *any* application code, in the main application or
shared libraries, before the main application's crt1 has executed,
because there are (essentially -- the equivalent of) self-relocations
performed at that stage that the dynamic linker can't see. If any
ctors were invoked directly by the dynamic linker before passing
control the the main application's entry point, they would run without<= br> these relocations in the main application having been performed,
possibly resulting in runaway-wrong execution.

I believe Go is doing some bad hacks here with regard to its C FFI,
but it's likely fixable in some reasonable way. We should get more
eyes looking at it.

Rich

--000000000000746be2057b2ec057--