Skip to content

Commit 8493467

Browse files
committed
[JITLink][AArch64] Ensure that nulls remain null during ptrauth signing.
Signing a null pointer value can, and usually will, result in some high bits being set, causing null checks to fail. E.g. in extern void __attribute__((weak_import)) f(void); void (*p) = &f; if f is undefined then p should be null (left unsigned). This patch updates lowerPointer64AuthEdgesToSigningFunction to check for Pointer64Authenticated edges to null targets. Where found, these edges are turned into plain Pointer64 edges (which we know from context will write a null value to the fixup location), and signing instructions for these locations are omitted from the signing function.
1 parent 80f34e2 commit 8493467

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

llvm/lib/ExecutionEngine/JITLink/aarch64.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,18 @@ Error lowerPointer64AuthEdgesToSigningFunction(LinkGraph &G) {
324324

325325
uint64_t EncodedInfo = E.getAddend();
326326
int32_t RealAddend = (uint32_t)(EncodedInfo & 0xffffffff);
327+
auto ValueToSign = E.getTarget().getAddress() + RealAddend;
328+
if (!ValueToSign) {
329+
LLVM_DEBUG(dbgs() << " " << B->getFixupAddress(E) << " <- null\n");
330+
E.setAddend(RealAddend);
331+
E.setKind(aarch64::Pointer64);
332+
continue;
333+
}
334+
327335
uint32_t InitialDiscriminator = (EncodedInfo >> 32) & 0xffff;
328336
bool AddressDiversify = (EncodedInfo >> 48) & 0x1;
329337
uint32_t Key = (EncodedInfo >> 49) & 0x3;
330338
uint32_t HighBits = EncodedInfo >> 51;
331-
auto ValueToSign = E.getTarget().getAddress() + RealAddend;
332339

333340
if (HighBits != 0x1000)
334341
return make_error<JITLinkError>(
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# RUN: llvm-mc -triple=arm64e-apple-macosx -filetype=obj -o %t.o %s
2+
# RUN: llvm-jitlink %t.o
3+
#
4+
# REQUIRES: system-darwin && host=arm64{{.*}}
5+
#
6+
# Check that arm64e ptrauth pass preserves nulls.
7+
#
8+
# Testcase derived from:
9+
# extern void __attribute__((weak_import)) f(void);
10+
# void (*p) = &f;
11+
#
12+
# int main(int argc, char *argv[]) {
13+
# return p ? 1 : 0;
14+
# }
15+
16+
.section __TEXT,__text,regular,pure_instructions
17+
.globl _main
18+
.p2align 2
19+
_main:
20+
adrp x8, _p@PAGE
21+
ldr x8, [x8, _p@PAGEOFF]
22+
cmp x8, #0
23+
cset w0, ne
24+
ret
25+
26+
.section __DATA,__data
27+
.globl _p
28+
.p2align 3, 0x0
29+
_p:
30+
.quad _f@AUTH(ia,0)
31+
32+
.weak_reference _f
33+
.weak_reference l_f.ptrauth
34+
.subsections_via_symbols

0 commit comments

Comments
 (0)