From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS31976 209.132.180.0/23 X-Spam-Status: No, score=-4.0 required=3.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 8D2381F466 for ; Tue, 4 Feb 2020 07:16:02 +0000 (UTC) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id:references :mime-version:content-type:in-reply-to; q=dns; s=default; b=Uzxc fG7qZ/NvLH7IML85UMF6dD8vf+/MuoqtpiM2ZA/IJBuOssR2/Hx5YB3+4CJ6WK9P iak+Nh3OD4yiFQ8V+K8ql5S8lWrs6Uj+Pa4CbNNSSP68bY+6l8/elcJCbl0XNA/a xUzdkVeu7PnTjFULtYLaSFhDBx3eiZDvJkf4P9s= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id:references :mime-version:content-type:in-reply-to; s=default; bh=rGq1vZ4oxd ejvOVNT6FT2ptTLqs=; b=luvNW6n+W+PLCPXRXu1WVRUJPvKoDFtZONlZ78tVGV OYJaKtQPCQOHj8hZyHK80yFdZPZXU0J6G8lGECqGZXj8RIfdIfLQ8T0LC0wNq8gy JPwMAakp0gxZ0tKAvpdfIRdTPbNwXAoKZ45qPmJGrr1P+iXxmIZ+tN5Bkl4Fe+VQ M= Received: (qmail 122880 invoked by alias); 4 Feb 2020 07:15:32 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 122266 invoked by uid 89); 4 Feb 2020 07:15:27 -0000 Authentication-Results: sourceware.org; auth=none X-HELO: mail-pl1-f180.google.com Date: Mon, 3 Feb 2020 23:15:21 -0800 From: Fangrui Song To: Carlos O'Donell Cc: Florian Weimer , Zack Weinberg , GNU C Library Subject: Re: Are ifuncs intended to be allowed to resolve to symbols in another DSO? Message-ID: <20200204071521.cawphkak4yjrax4t@google.com> References: <87sgko4b91.fsf@oldenburg2.str.redhat.com> <559bbced-2f06-4196-719a-923e6c804e1d@redhat.com> <87tv47jv05.fsf@oldenburg2.str.redhat.com> <7012c618-01f4-1e4d-51d0-6491a5e61e2f@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <7012c618-01f4-1e4d-51d0-6491a5e61e2f@redhat.com> On 2020-02-03, Carlos O'Donell wrote: >On 2/3/20 3:06 PM, Florian Weimer wrote: >> * Carlos O'Donell: >> >>> If an IFUNC resolver calls a function which is not yet resolved then >>> isn't that a defect in the IFUNC resolver? >> >> There is a position that an IFUNC resolver must not use any non-local >> relocations. (We must support some relocations for IFUNCs on >> !PI_STATIC_AND_HIDDEN targets.) In this case, yes, such a dependencies >> would be a bug because all external dependencies are bugs. > >Just so I understand the position is, to simplify the implementation, that >IFUNC resolvers must not use any non-local relocations? > >What does non-local relocations mean? Are we saying the target of all >relocations must be within the same linkmap as the resolver? Are we saying >then that resolvers can only manipulate local data and make local function >calls? > >I don't think that would be useful since you'd want to call many libc functions >from the resolver itself and so you would have calls in the resolver that >could call through a GOT entry that has a relocation against an external >symbol in another DSO e.g. libc.so.6. > >If an IFUNC resolver has relocations that against non-local symbols >then those symbols must have been a dependency of the object and listed >in DT_NEEDED and therefore relocated before the current IFUNC resolver >is running. > >> On the other hand, in glibc, we could get rid of many IFUNC resolvers >> which violate this rule only after changing the loader that eliminated >> their need for them. Other IFUNCs that do not follow this rule do not >> have this luxury. > >I don't quite parse your first setnence here, could you expand on that please? > >When you speak about luxury, you mean to say that IFUNCs in other projects >would not have the same possibility to solve such a problem like we do in >glibc? > >>> The code which contains such an IFUNC should have had a DT_NEEDED entry >>> on all objects to which the resolver called into? >> >> This does not help with symbol interposition. > >What exact problem does symbol interposition cause? > >>> I like solutions that ensure that IFUNC resolvers, which are just foreign >>> functions, run@a stage *after* their own dependencies have been resolved, >>> but before their own initializers have run. >> >> Lazy binding achieves this because it implicitly tracks this dependency >> information. For eager binding, we simply do not have this information. >> Hence my patch for delayed relocation processing. But it does not solve >> the problem completely, of course. > >The dependencies are explicitly tracked by DT_NEEDED. > >Then when we have underlinked libraries we try to suppliment this and reorder >by relocation dependencies. This may be causing more problems than it solves? > >If we had good visibility into the load order manipulations because of the >relocations I think users would understand the consequences of these problems >and we would also be able to better identify underlinked applications and file >bugs to fix them (if possible). On powerpc64: A is in one module, B and C are in another module. C is a non-preemptible ifunc. A calls B, B tail calls C. The GNU ld generated IPLT code sequence starts with `std r2,24(r1)` . When B tail calls C, it has popped its stack frame. `std r2,24(r1)` overwrites the TOC pointer from A's module with the TOC pointer from B,C's module. When C returns to the call site in A, the TOC pointer incorrectly restores to the value from B,C's module. The lld generated IPLT code sequence does not use `std r2,24(r1)`. The above scenario works, but the resolver and the implementation cannot be in different modules. So for powerpc64, an IFUNC resolver returning the implementation in another module may be unreliable. On powerpc32 Secure PLT: A is in one translation unit, B and C are in another translation units. A, B and C are in the same module. C is a non-preemptible ifunc. B takes the address of C and passes it to A. A calls the function pointer. The IPLT code sequence assumes r30 = .got2(B)+0x8000. Calling it from A (.got2(A)!=.got2(B)) will be wrong. So for powerpc, even different translation units can be unreliable.