Skip to content

Commit c28b18a

Browse files
committed
[KernelAddressSanitizer] Fix globals exclusion for indirect aliases
GlobalAlias::getAliasee() may not always point directly to a GlobalVariable. In such cases, try to find the canonical GlobalVariable that the alias refers to. Link: ClangBuiltLinux/linux#1208 Reviewed By: dvyukov, nickdesaulniers Differential Revision: https://reviews.llvm.org/D92846
1 parent d863a0d commit c28b18a

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

clang/test/CodeGen/asan-globals-alias.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,42 @@
11
// RUN: %clang_cc1 -triple x86_64-linux -fsanitize=address -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,ASAN
2+
// RUN: %clang_cc1 -triple x86_64-linux -O2 -fsanitize=address -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,ASAN
23
// RUN: %clang_cc1 -triple x86_64-linux -fsanitize=kernel-address -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,KASAN
4+
// RUN: %clang_cc1 -triple x86_64-linux -O2 -fsanitize=kernel-address -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,KASAN
35
//
46
// Not all platforms support aliases - test for Linux only.
57

6-
int global; // to generate ctor for at least 1 global
7-
int aliased_global; // KASAN - ignore globals prefixed by aliases with __-prefix (below)
8-
extern int __attribute__((alias("aliased_global"))) __global_alias; // KASAN - aliased_global ignored
8+
int global; // generate ctor for at least 1 global
9+
int aliased_global; // KASAN ignored
10+
extern int __attribute__((alias("aliased_global"))) __global_alias;
11+
12+
// Recursive alias:
13+
int aliased_global_2; // KASAN ignored
14+
extern int __attribute__((alias("aliased_global_2"))) global_alias_2;
15+
extern int __attribute__((alias("global_alias_2"))) __global_alias_2_alias;
16+
17+
// Potential indirect alias:
18+
struct input_device_id {
19+
unsigned long keybit[24];
20+
unsigned long driver_info;
21+
};
22+
struct input_device_id joydev_ids[] = { { {1}, 1234 } }; // KASAN ignored
23+
extern struct input_device_id __attribute__((alias("joydev_ids"))) __mod_joydev_ids_device_table;
924

1025
// ASAN: @aliased_global{{.*}} global { i32, [60 x i8] }{{.*}}, align 32
26+
// ASAN: @aliased_global_2{{.*}} global { i32, [60 x i8] }{{.*}}, align 32
27+
// ASAN: @joydev_ids{{.*}} global { {{.*}}[56 x i8] zeroinitializer }, align 32
1128
// KASAN: @aliased_global{{.*}} global i32
29+
// KASAN: @aliased_global_2{{.*}} global i32
30+
// KASAN: @joydev_ids{{.*}} global [1 x {{.*}}i64 1234 }], align 16
31+
32+
// Check the aliases exist:
33+
// CHECK: @__global_alias = alias
34+
// CHECK: @global_alias_2 = alias
35+
// CHECK: @__global_alias_2_alias = alias
36+
// CHECK: @__mod_joydev_ids_device_table = alias
1237

1338
// CHECK-LABEL: define internal void @asan.module_ctor
14-
// ASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 2)
39+
// ASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 4)
1540
// KASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 1)
1641
// CHECK-NEXT: ret void
1742

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ class ModuleAddressSanitizer {
792792
StringRef InternalSuffix);
793793
Instruction *CreateAsanModuleDtor(Module &M);
794794

795-
bool canInstrumentAliasedGlobal(const GlobalAlias &GA) const;
795+
const GlobalVariable *getExcludedAliasedGlobal(const GlobalAlias &GA) const;
796796
bool shouldInstrumentGlobal(GlobalVariable *G) const;
797797
bool ShouldUseMachOGlobalsSection() const;
798798
StringRef getGlobalMetadataSection() const;
@@ -1787,20 +1787,22 @@ void ModuleAddressSanitizer::createInitializerPoisonCalls(
17871787
}
17881788
}
17891789

1790-
bool ModuleAddressSanitizer::canInstrumentAliasedGlobal(
1791-
const GlobalAlias &GA) const {
1790+
const GlobalVariable *
1791+
ModuleAddressSanitizer::getExcludedAliasedGlobal(const GlobalAlias &GA) const {
17921792
// In case this function should be expanded to include rules that do not just
17931793
// apply when CompileKernel is true, either guard all existing rules with an
17941794
// 'if (CompileKernel) { ... }' or be absolutely sure that all these rules
17951795
// should also apply to user space.
17961796
assert(CompileKernel && "Only expecting to be called when compiling kernel");
17971797

1798+
const Constant *C = GA.getAliasee();
1799+
17981800
// When compiling the kernel, globals that are aliased by symbols prefixed
17991801
// by "__" are special and cannot be padded with a redzone.
18001802
if (GA.getName().startswith("__"))
1801-
return false;
1803+
return dyn_cast<GlobalVariable>(C->stripPointerCastsAndAliases());
18021804

1803-
return true;
1805+
return nullptr;
18041806
}
18051807

18061808
bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
@@ -2252,14 +2254,12 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
22522254
*CtorComdat = false;
22532255

22542256
// Build set of globals that are aliased by some GA, where
2255-
// canInstrumentAliasedGlobal(GA) returns false.
2257+
// getExcludedAliasedGlobal(GA) returns the relevant GlobalVariable.
22562258
SmallPtrSet<const GlobalVariable *, 16> AliasedGlobalExclusions;
22572259
if (CompileKernel) {
22582260
for (auto &GA : M.aliases()) {
2259-
if (const auto *GV = dyn_cast<GlobalVariable>(GA.getAliasee())) {
2260-
if (!canInstrumentAliasedGlobal(GA))
2261-
AliasedGlobalExclusions.insert(GV);
2262-
}
2261+
if (const GlobalVariable *GV = getExcludedAliasedGlobal(GA))
2262+
AliasedGlobalExclusions.insert(GV);
22632263
}
22642264
}
22652265

0 commit comments

Comments
 (0)