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 | 57d82ee080758dbcea790c879ea68971d6aa6e95 (patch) | |
tree | 140f0a308648cd284122ccbc5555054c0ab611d4 /tools/llvm-readobj | |
parent | 24775560e220895c25331a17bd8db4d2b6462ed1 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325047 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-readobj')
-rw-r--r-- | tools/llvm-readobj/COFFDumper.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index a6a2c197741..40334802d8e 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -67,6 +67,8 @@ struct LoadConfigTables { uint32_t GuardFlags = 0; uint64_t GuardFidTableVA = 0; uint64_t GuardFidTableCount = 0; + uint64_t GuardLJmpTableVA = 0; + uint64_t GuardLJmpTableCount = 0; }; class COFFDumper : public ObjDumper { @@ -800,6 +802,11 @@ void COFFDumper::printCOFFLoadConfig() { printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 4); } } + + if (Tables.GuardLJmpTableVA) { + ListScope LS(W, "GuardLJmpTable"); + printRVATable(Tables.GuardLJmpTableVA, Tables.GuardLJmpTableCount, 4); + } } template <typename T> @@ -879,6 +886,9 @@ void COFFDumper::printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables) { W.printHex("GuardRFVerifyStackPointerFunctionPointer", Conf->GuardRFVerifyStackPointerFunctionPointer); W.printHex("HotPatchTableOffset", Conf->HotPatchTableOffset); + + Tables.GuardLJmpTableVA = Conf->GuardLongJumpTargetTable; + Tables.GuardLJmpTableCount = Conf->GuardLongJumpTargetCount; } void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) { |