diff options
author | Reid Kleckner <rnk@google.com> | 2018-02-13 20:32:53 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2018-02-13 20:32:53 +0000 |
commit | fd520962590350c8072394771ced45b15ee93002 (patch) | |
tree | bc17059c19f4d355f005887d21277623a5593354 /lld/COFF/Config.h | |
parent | 447ae4044dd37c30f01e250a5a6101002ad77e87 (diff) | |
download | bcm5719-llvm-fd520962590350c8072394771ced45b15ee93002.tar.gz bcm5719-llvm-fd520962590350c8072394771ced45b15ee93002.zip |
[LLD] Implement /guard:[no]longjmp
Summary:
This protects calls to longjmp from transferring control to arbitrary
program points. Instead, longjmp calls are limited to the set of
registered setjmp return addresses.
This also implements /guard:nolongjmp to allow users to link in object
files that call setjmp that weren't compiled with /guard:cf. In this
case, the linker will approximate the set of address taken functions,
but it will leave longjmp unprotected.
I used the following program to test, compiling it with different -guard
flags:
$ cl -c t.c -guard:cf
$ lld-link t.obj -guard:cf
#include <setjmp.h>
#include <stdio.h>
jmp_buf buf;
void g() {
printf("before longjmp\n");
fflush(stdout);
longjmp(buf, 1);
}
void f() {
if (setjmp(buf)) {
printf("setjmp returned non-zero\n");
return;
}
g();
}
int main() {
f();
printf("hello world\n");
}
In particular, the program aborts when the code is compiled *without*
-guard:cf and linked with -guard:cf. That indicates that longjmps are
protected.
Reviewers: ruiu, inglorion, amccarth
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D43217
llvm-svn: 325047
Diffstat (limited to 'lld/COFF/Config.h')
-rw-r--r-- | lld/COFF/Config.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 4a4d6d189e1..c3e973077cf 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -72,6 +72,12 @@ enum class DebugType { Fixup = 0x4, /// Relocation Table }; +enum class GuardCFLevel { + Off, + NoLongJmp, // Emit gfids but no longjmp tables + Full, // Enable all protections. +}; + // Global configuration. struct Configuration { enum ManifestKind { SideBySide, Embed, No }; @@ -113,7 +119,7 @@ struct Configuration { bool SaveTemps = false; // /guard:cf - bool GuardCF; + GuardCFLevel GuardCF = GuardCFLevel::Off; // Used for SafeSEH. Symbol *SEHTable = nullptr; |