[PATCH v4 07/12] aarch64: enable BTI at runtime

H.J. Lu hjl.tools@gmail.com
Fri Jun 12 15:18:41 GMT 2020

On Fri, Jun 12, 2020 at 8:08 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> The 06/12/2020 06:43, H.J. Lu wrote:
> > On Fri, Jun 12, 2020 at 6:34 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> > >
> > > From: Sudakshina Das <sudi.das@arm.com>
> > >
> > > Binaries can opt-in to using BTI via an ELF object file marking.
> > > The dynamic linker has to then mprotect the executable segments
> > > with PROT_BTI. In case of static linked executables or in case
> > > of the dynamic linker itself, PROT_BTI protection is done by the
> > > operating system.
> > >
> > > On AArch64 glibc uses PT_GNU_PROPERTY instead of PT_NOTE to check
> > > the properties of a binary because PT_NOTE can be unreliable with
> > > old linkers (old linkers just append the notes of input objects
> > > together and add them to the output without checking them for
> > > consistency which means multiple incompatible GNU property notes
> > > can be present in PT_NOTE). A new _dl_process_pt_gnu_property
> > > hook is introduced in dl-prop.h and to keep it maintainable the
> > > rtld and dlopen code paths use the same function (if the main
> > > map needs special treatment, that should be inferred by the hook
> > > from the link map). Unlike the _dt_process_pt_note hook this one
> > > is called after segments are mapped to avoid unbounded allocation
> > > and additional read syscall. Otherwise the AArch64 logic follows
> > > the x86 logic for handling GNU properties (but the code is not
> > > shared because x86 needs to manage internal CET state and look
> > > out for multiple property notes).
> >
> > Can you make _dl_process_pt_gnu_property more generic so that it
> > can be shared with x86?  If there is PT_GNU_PROPERTY, we don't
> > need to check for multiple property notes.  Thanks.
> it can use a hook for NT_GNU_PROPERTY_TYPE_0 notes
> that is called for each property, e.g.
> int
> _dl_process_gnu_property_note0(uint32_t type, uint32_t datasz, const void *data);
> and then a target only needs to override that. i
> assume the rest of the PT_GNU_PROPERTY handling
> can be generic. (the int return value can control
> if processing should stop or continue)
> however this only helps on x86 if PT_GNU_PROPERTY
> processing is before PT_NOTE processing otherwise
> you cannot skip handling the notes.
> i moved the _dl_process_pt_gnu_property into a
> second pass in dl-load.c so load segments are
> mapped by then, the note processing is currently
> before that (but even if that's moved into the
> second pass, PT_NOTE i think will appear before
> PT_GNU_PROPERTY in the program headers), so it's
> not clear if refactoring helps: you would need
> separate target hooks for first and second passes
> over pt headers i think.

On x86-64, there are

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000003628 0x0000000000003628  R      0x1000
  LOAD           0x0000000000004000 0x0000000000004000 0x0000000000004000
                 0x0000000000014541 0x0000000000014541  R E    0x1000
  LOAD           0x0000000000019000 0x0000000000019000 0x0000000000019000
                 0x0000000000008e18 0x0000000000008e18  R      0x1000
  LOAD           0x0000000000021f50 0x0000000000022f50 0x0000000000022f50
                 0x00000000000012f8 0x00000000000025a8  RW     0x1000
  DYNAMIC        0x00000000000229f8 0x00000000000239f8 0x00000000000239f8
                 0x0000000000000210 0x0000000000000210  RW     0x8
  NOTE           0x0000000000000338 0x0000000000000338 0x0000000000000338
                 0x0000000000000020 0x0000000000000020  R      0x8
  NOTE           0x0000000000000358 0x0000000000000358 0x0000000000000358
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_PROPERTY   0x0000000000000338 0x0000000000000338 0x0000000000000338
                 0x0000000000000020 0x0000000000000020  R      0x8
  GNU_EH_FRAME   0x000000000001e32c 0x000000000001e32c 0x000000000001e32c
                 0x00000000000008fc 0x00000000000008fc  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000021f50 0x0000000000022f50 0x0000000000022f50
                 0x00000000000010b0 0x00000000000010b0  R      0x1

Only the PT_NOTE segment with the correct alignment may contain property.
In the first pass, we record such PT_NOTE segment, but don't process it.
After all segments have been processed, we process the saved PT_NOTE segment
if there is no GNU_PROPERTY segment.


More information about the Libc-alpha mailing list