From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5688 invoked by alias); 22 Mar 2018 11:06:07 -0000 Mailing-List: contact gnu-gabi-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: gnu-gabi-owner@sourceware.org Received: (qmail 5280 invoked by uid 89); 22 Mar 2018 11:06:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=wishes X-Spam-Status: No, score=-2.8 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: mail-oi0-f47.google.com Received: from mail-oi0-f47.google.com (HELO mail-oi0-f47.google.com) (209.85.218.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 22 Mar 2018 11:06:03 +0000 Received: by mail-oi0-f47.google.com with SMTP id 23-v6so6959293oir.11 for ; Thu, 22 Mar 2018 04:06:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=qVZ2JITjfmZ70JmpWIHYhyn9xC4CJmQC/5yCPskP00Q=; b=UMZiZvyIeIVwV5V6Mhvn7GF4go9uTokixO5H0JPXQzX2Tnx67YSYJbQEFrEEBUjOiw g/Fa+3XDfp71YQtgmcFWzQhbc48pMgtbwA+2NxEFyEjVpX08XMGixIATCS0aLq6qxV7j HafTpQFxPcJd1fw8K4EifYJyHu0KXLPGqpVGDxwL2gWfsVKa+hGJ1D0xwfZjwDAK6nVM wabvJasCAfnUpVtz0tu56H+VVOeEpPV7j9jMBsGsqrcW3dF047iibcvRtQsekFLmDoSh rVew1sl+ZYQhY5pVR8MJFigXs6BPC44rKDD5tQE2ENeilLiNP5GOn6gBUKoR+GDw5b3c 1JCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=qVZ2JITjfmZ70JmpWIHYhyn9xC4CJmQC/5yCPskP00Q=; b=h3B6LZ2hmMgB027cqa6pPdooBfBMBp6ZYXdqfQSx+mYWvwqUDGws5niiZJ/tqA90eu SZG9xwifNII3zoBzzr3r306dkVepSfWNJRbpYsVqq/+0m+6untg5Qouig60WJqtkBRI4 Xgc2QjCkiEC/dL9ka1h5IKuSNUpbeWiddnRLtGwDC02aoeIc48D3rOAgEQDu7+XPeAKL IGNH3FLF8uFrEtz//e9uYnrKsCBGQOPFMESZRD79p+F/+/KTp9vAruarZDMti7VHPhEj InP2miHlu3WNL6ahUODpE4a823wTil24Iay4ejZnrcBc+x/mGCtmP0qwWclmMpjyiS5d k3Dw== X-Gm-Message-State: AElRT7FVeIkWQRhmIi9nfaYAOxOpgVrhkE4LatDqE9jZOb0R/jP228n+ vd4+s/xTEMg3XpBKW3l7AzWgOX9uXI15gDiQtrs= X-Google-Smtp-Source: AG47ELsLdNNEcHwG5PISVni/p1zY8NH9cibUV8rfo3CqqiiFwEjuNpZkaqHNt1Md9Tan0aVRSU+CsgJILaOpZbGqAw0= X-Received: by 10.202.234.70 with SMTP id i67mr13143201oih.316.1521716761416; Thu, 22 Mar 2018 04:06:01 -0700 (PDT) MIME-Version: 1.0 Received: by 10.74.10.20 with HTTP; Thu, 22 Mar 2018 04:06:00 -0700 (PDT) In-Reply-To: References: <20180317133115.GA4681@gmail.com> From: "H.J. Lu" Date: Mon, 01 Jan 2018 00:00:00 -0000 Message-ID: Subject: Re: RFC: Audit external function called indirectly via GOT To: Generic System V Application Binary Interface Cc: "Carlos O'Donell" , gnu-gabi@sourceware.org Content-Type: text/plain; charset="UTF-8" X-IsSubscribed: yes X-SW-Source: 2018-q1/txt/msg00010.txt.bz2 On Wed, Mar 21, 2018 at 10:15 PM, Cary Coutant wrote: >> To be specific we are talking about the Solaris LD_AUDIT support that is >> implemented in the GNU dynamic loader ld.so. This has been a very useful >> thing for developers to have, particularly those working on schemes that >> alter lookup paths or binding rules. Also those that use these hooks to >> do other useful auditing. There were a lot of Solaris LD_AUDIT users, and >> now there are a lot of users that use this same feature in the GNU tools. > > The description of la_symbind*() says this: > > "The return value of la_symbind32() and la_symbind64() is the address > to which control should be passed after the function returns. If the > auditing library is simply monitoring symbol bindings, then it should > return sym->st_value. A different value may be returned if the > library wishes to direct control to an alternate location." > > That implies that it is called only for symbols that are > dynamically-bound (i.e., lazy binding). Does this mean that you want > to cancel the immediate binding effects of -fno-plt? > >> The problem comes when you build with -fno-plt, or if you elide a PLT slot >> for any other reason, there is no longer a place for the LD_AUDIT >> infrastructure to hook into. >> >> In the case of x86 the -fno-plt generated code is a direct call through >> the GOT. The GOT is RO after relocation (relro), and so most tooling expects >> that it cannot be changed. Therefore it's not entirely kosher to reuse the >> GOT for this purpose, though you could do that, in fact on x86 the GLOB_DAT >> reloc and GOT entry look an awful lot like a function descriptor and a call >> through that function descriptor (for arches that have non-code PLTs). >> >> By keeping the generation of the PLT slot, but not using it, you can go back >> and re-use that PLT entry for auditing. If you are RELRO then you are going >> to pay a performance cost for turning on auditing, you will be forced to >> go through the PLT call sequence every time, enter the loader, find your >> already computed resolution in the loader's cache, and continue. If you are >> non-RELRO you can finalize the binding in the PLT. > > I'm not sure if you're saying that this is worse with -fno-plt than > without. Wouldn't you have the same performance cost either way, if > auditing is turned on? > >> What does "statically relocated" mean? > > If I'm reading HJ's proposal correctly, he's got: (1) a regular GOT > entry (with a GLOB_DAT relocation), (2) a "provisional" PLTGOT entry > (with a JUMP_SLOT relocation), and (3) a "provisional" PLT entry for > each external function, and all these extra dynamic table entries are > there so that: > > (1) the dynamic loader can find the provisional PLTGOT entry for the > same function by matching the GLOB_DAT relocations with the JUMP_SLOT > relocations, > (2) use that to find the corresponding provisional PLT entry, > (3) relocate the GOT entry to point to that PLT entry, > (4) which will then proceed to use the PLTGOT entry for binding as if > -fno-plt had not been used. That is correct. > My suggestion was that the GOT entry could be statically initialized > by the linker to point to the provisional PLT entry, rather than > forcing the dynamic loader to go through all this messy computation. > If auditing is not enabled, it would process the GLOB_DAT relocation > normally, and set the GOT entry to point to the actual function, elf_machine_plt_address in my glibc patch: https://github.com/hjl-tools/glibc/commit/aa8f2f5b9f395769f30d776649a11c2a045dd9e2 has if (__glibc_unlikely (GLRO(dl_naudit) > 0) && map->l_info[ADDRIDX (DT_GNU_PLT)] && map->l_info[DT_JMPREL] && ELFW(ST_TYPE) (refsym->st_info) == STT_FUNC) { Find the matching JUMP_SLOT relocation. } else Use the original resolution. If LD_AUDIT is unused, the whole thing is skipped. > bypassing the provisional PLT and PLTGOT entries completely. If > auditing is enabled, it could simply ignore the GLOB_DAT relocation > (or, if the binary is PIE, it could process it as a RELATIVE > relocation), and the -fno-plt calls will end up jumping to the > provisional PLT entry. > > (This is already how we handle the PLTGOT entries: the linker > statically initializes the entries to point to part (b)* of the PLT > entry, while putting JUMP_SLOT relocations for those entries into the > JMPREL table.) > > I think if you do that, none of these extra dynamic table entries will > be needed, except for the IGNORE_JMPREL flag that indicates there are > no JMPREL slots other than those for the provisional PLT entries. How > useful is that flag? If the final program has even one external call > that was *not* compiled with -fno-plt, you won't be able to set it. > Would it be better to partition the JMPREL and PLT tables into > "regular" and "provisional" entries? That would take just a single new > DT_PROVISIONAL_JMPREL entry to tell the dynamic loader where the > JMPREL entries for the provisional PLT entries begin; it can ignore > everything past that point when auditing is turned off. These new dynamic tags are used to compute PLT offset from GOT offset. See elf_machine_plt_address in my patch. > I suppose you may also want to partition the GLOB_DAT relocations, so > that the dynamic loader can easily figure out which ones to ignore > when auditing is enabled. That would take another dynamic table entry. > > Now, why do we need both the regular GOT entry and the provisional > PLTGOT entry? If the program is linked with -z relro and lazy binding, > you can put the GOT entries in the RELRO segment, and the PLTGOT > entries in writable data. That gives you the security when auditing is > turned off, and the ability to dynamically patch the PLTGOT when it's > turned on. In any other case, however, I see no reason to have both. > If you get rid of the GOT entry, and have the point of call jump > indirectly through the PLTGOT entry, which is initialized to point to > part (b) of the PLT entry, everything should work the same as without > -fno-plt. Essentially, all -fno-plt would do is inline part (a) of the > PLT entry. > I want to use both so that GOT is read-only after relocation in normal case and the writable PLTGOT is only used for LD_AUDIT. -- H.J.