[llvm-dev] [LLD/ELF] - Should we implement .note.gnu.property and/or Intel CET in LLD ?

George Rimar via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 20 06:59:16 PDT 2018


Linux GABI [1] introduced new .note.gnu.property section which contains a program
property note which describes special handling requirements for linker and run-time loader.

LLD does not support .note.gnu.property yet.

GABI specifies 2 types of entries:
GNU_PROPERTY_STACK_SIZE and GNU_PROPERTY_NO_COPY_ON_PROTECTED:

* GNU_PROPERTY_STACK_SIZE: Its pr_data field contains an integer in the format
of the target processor. Linker should select the maximum value among all input
relocatable objects and copy this property to the output. Run-time loader should
raise the stack limit to the value specified in this property.
* GNU_PROPERTY_NO_COPY_ON_PROTECTED: This indicates that there should be no
copy relocations against protected data symbols. If a relocatable object contains this
property, linker should treat protected data symbol as defined locally at run-time and
copy this property to the output share object. Linker should add this property to the
output share object if any protected symbol is expected to be defined locally at run-time.
Run-time loader should disallow copy relocations against protected data symbols defined
in share objects with GNU_PROPERTY_NO_COPY_ON_PROTECTED property.
Its PR_DATASZ should be 0.

I am not sure how much the second is useful because I think LLD now restricts
doing the copy relocations against protected symbols,
so probably we can ignore it ATM.

The first is a bit more interesting. We do not proccess this notes and our output
is broken now, we just merge all records and seems have the same issue as gold has:
https://sourceware.org/bugzilla/show_bug.cgi?id=22914.<https://sourceware.org/bugzilla/show_bug.cgi?id=22914>
At the same time as far I know, Linux kernel does not yet has support for
GNU_PROPERTY_STACK_SIZE, so it probably means there are no users at all for it in the wild.

On another side, we have an Intel CET [2], [3]:
"Control-flow Enforcement Technology (CET) provides the following capabilities to defend
against ROP/JOP style control-flow subversion attacks:
- Shadow Stack - return address protection to defend against Return Oriented Programming,
- Indirect branch tracking - free branch protection to defend against Jump/Call Oriented Programming.​"

Intel CET uses following processor-specific program property types in .note.gnu.property [3, p85, p87]:

* GNU_PROPERTY_X86_FEATURE_1_IBT This indicates that all executable sections are compatible
with IBT (see Section 13.1.1) when endbr64 instruction starts each valid target where an indirect
branch instruction can land. 8
* GNU_PROPERTY_X86_FEATURE_1_SHSTK This indicates that all executable sections are compatible
with SHSTK (see Section 13.1.2) where return address popped from shadow stack always matches
return address popped from normal stack.

It is not yet supported by gold: https://sourceware.org/bugzilla/show_bug.cgi?id=22915
But supported by bfd: https://sourceware.org/ml/binutils/2017-06/msg00285.html

Support requires both compiler and linker changes.

Also [3, p151] says that to support IBT the linker should generate a IBT-enabled PLT
together with a second PLT. That is also what is implemented in bfd it seems:
https://sourceware.org/ml/binutils/2017-06/msg00285.html.

GCC started to support it recently and already uses it for building
libobjc, libgfortran, libmpx, libstdc++-v3, libatomic, libbacktrace and other libs:
* https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=3c0f15b4cebccdbb6388a8df5933e69c9b773149
* https://gcc.gnu.org/git/?p=gcc.git&a=search&h=743b05ae4918eac3437965016649b2cabbdbb819&st=commit&s=intel+cet

Technology is backwards compatible. I used GCC version 8.0.1 20180319
(experimental) for experiments.
For following code and invocations:
1.cpp:
int xxx() { return 1; }

/usr/local/bin/gcc 1.cpp -c -o test1.o -fcf-protection=full -mcet -B.
/usr/local/bin/gcc 1.cpp -c -o test2.o -B.

Compiler will generate special instructions and emit .note.gnu.property section.
test1.o:
0000000000000000 <_Z3xxxv>:
   0: f3 0f 1e fa          endbr64
   4: b8 01 00 00 00        mov    $0x1,%eax
   9: c3                    retq

readelf output:
Displaying notes found in: .note.gnu.property
  Owner                 Data size Description
  GNU                  0x00000010 NT_GNU_PROPERTY_TYPE_0
      Properties: x86 feature: IBT, SHSTK

test2.o (no CET):
0000000000000000 <_Z3xxxv>:
   0: b8 01 00 00 00        mov    $0x1,%eax
   5: c3                    retq

endbr64 is no-op (for CPUs that do not support CET), more details are in specs above.
An important part for the linker
is that it should support .note.gnu.property to properly handle and combine
x86 specific properties or reject them, since with dumb merging of sections we seems
produce broken output here again.

Given all above I suggest to:
1) Implement .note.gnu.property and support GNU_PROPERTY_STACK_SIZE​ + GNU_PROPERTY_NO_COPY_ON_PROTECTED
2) For start - error out on all other flags we do not explicitly support (like GNU_PROPERTY_X86_FEATURE_*, GNU_PROPERTY_X86_ISA_* and others
on p86-p88 of [3]).
3) Deside if we want to support Intel CET.


[1] - Linux GABI https://github.com/hjl-tools/linux-abi/wiki/linux-abi-draft.pdf

[2] - "CONTROL-FLOW ENFORCEMENT TECHNOLOGY PREVIEW" (https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf)

[3] - "System V Application Binary Interface" ch.13 (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-cet.pdf)


Best regards,
George | Developer | Access Softek, Inc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180320/b2687b84/attachment.html>


More information about the llvm-dev mailing list