[clang] Disable memtag sanitization for global fnptrs going into .ctors (PR #70186)
Mitch Phillips via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 25 02:39:02 PDT 2023
https://github.com/hctim created https://github.com/llvm/llvm-project/pull/70186
Looks like there's code out there that, instead of using
'__attribute__((constructor(x)))' to add constructor functions, they
just declare a global function pointer and use
'__attribute__((section('.ctors')))' instead.
Problem is, with memtag-globals, we pad the global function pointer to
be 16 bytes large. This of course means we have an 8-byte real function
pointer, then 8 bytes of zero padding, and this trips up the loader when
it processes this section.
Fixes #69939
>From f70a2dba661163a436c40e9e8f97cd9a27a726ca Mon Sep 17 00:00:00 2001
From: Mitch Phillips <mitchp at google.com>
Date: Wed, 25 Oct 2023 11:35:29 +0200
Subject: [PATCH] Disable memtag sanitization for global fnptrs going into
.ctors
Looks like there's code out there that, instead of using
'__attribute__((constructor(x)))' to add constructor functions, they
just declare a global function pointer and use
'__attribute__((section('.ctors')))' instead.
Problem is, with memtag-globals, we pad the global function pointer to
be 16 bytes large. This of course means we have an 8-byte real function
pointer, then 8 bytes of zero padding, and this trips up the loader when
it processes this section.
Fixes #69939
---
clang/test/CodeGen/memtag-globals-asm.cpp | 20 +++++++++++++++++++
.../Target/AArch64/AArch64GlobalsTagging.cpp | 12 +++++++++++
2 files changed, 32 insertions(+)
diff --git a/clang/test/CodeGen/memtag-globals-asm.cpp b/clang/test/CodeGen/memtag-globals-asm.cpp
index 3f18671562def71..4b76b394e0c1dc3 100644
--- a/clang/test/CodeGen/memtag-globals-asm.cpp
+++ b/clang/test/CodeGen/memtag-globals-asm.cpp
@@ -259,3 +259,23 @@ int f(int x) {
// CHECK-Q-DAG: ldr {{.*}}, [[[REG_O2]]]
function_int;
}
+
+typedef void (*func_t)(void);
+#define CONSTRUCTOR(section_name) \
+ __attribute__((used)) __attribute__((section(section_name)))
+
+__attribute__((constructor(0))) void func_constructor() {}
+CONSTRUCTOR(".init") func_t func_init = func_constructor;
+CONSTRUCTOR(".fini") func_t func_fini = func_constructor;
+CONSTRUCTOR(".ctors") func_t func_ctors = func_constructor;
+CONSTRUCTOR(".dtors") func_t func_dtors = func_constructor;
+CONSTRUCTOR(".init_array") func_t func_init_array = func_constructor;
+CONSTRUCTOR(".fini_array") func_t func_fini_array = func_constructor;
+
+// CHECK-NOT: .memtag func_constructor
+// CHECK-NOT: .memtag func_init
+// CHECK-NOT: .memtag func_fini
+// CHECK-NOT: .memtag func_ctors
+// CHECK-NOT: .memtag func_dtors
+// CHECK-NOT: .memtag func_init_array
+// CHECK-NOT: .memtag func_fini_array
diff --git a/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp b/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp
index 2ed668712897ce7..88e44eb0bfbb99f 100644
--- a/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp
+++ b/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp
@@ -43,6 +43,18 @@ static bool shouldTagGlobal(GlobalVariable &G) {
return false;
}
+ // Don't instrument function pointers that are going into various init arrays
+ // via `__attribute__((section(<foo>)))`:
+ // https://github.com/llvm/llvm-project/issues/69939
+ if (G.hasSection() &&
+ (G.getSection() == ".init" || G.getSection() == ".fini" ||
+ G.getSection() == ".init_array" || G.getSection() == ".fini_array" ||
+ G.getSection() == ".ctors" || G.getSection() == ".dtors")) {
+ Meta.Memtag = false;
+ G.setSanitizerMetadata(Meta);
+ return false;
+ }
+
return true;
}
More information about the cfe-commits
mailing list