Skip to content

Commit 981c58e

Browse files
authored
Add -fsanitize-address-use-after-return (#4334)
1 parent 8ed521d commit 981c58e

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

driver/cl_options_sanitizers.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@
2525
#include "llvm/Support/VirtualFileSystem.h"
2626
#endif
2727

28+
#if LDC_LLVM_VER >= 1400
29+
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
30+
#else
31+
namespace llvm {
32+
// Declaring this simplifies code later, but the option is never used with LLVM
33+
// <= 13.
34+
enum class AsanDetectStackUseAfterReturnMode { Never, Runtime, Always };
35+
}
36+
#endif
37+
2838
namespace {
2939

3040
using namespace opts;
@@ -121,6 +131,25 @@ void parseFSanitizeCoverageCmdlineParameter(llvm::SanitizerCoverageOptions &opts
121131

122132
namespace opts {
123133

134+
cl::opt<llvm::AsanDetectStackUseAfterReturnMode> fSanitizeAddressUseAfterReturn(
135+
"fsanitize-address-use-after-return", cl::ZeroOrMore,
136+
cl::desc("Select the mode of detecting stack use-after-return (UAR) in "
137+
"AddressSanitizer: never | runtime (default) | always"),
138+
cl::init(llvm::AsanDetectStackUseAfterReturnMode::Runtime),
139+
cl::values(
140+
clEnumValN(
141+
llvm::AsanDetectStackUseAfterReturnMode::Never, "never",
142+
"Completely disables detection of UAR errors (reduces code size)."),
143+
clEnumValN(llvm::AsanDetectStackUseAfterReturnMode::Runtime, "runtime",
144+
"Adds the code for detection, but it can be disabled via the "
145+
"runtime environment "
146+
"(ASAN_OPTIONS=detect_stack_use_after_return=0). Requires "
147+
"druntime support."),
148+
clEnumValN(
149+
llvm::AsanDetectStackUseAfterReturnMode::Always, "always",
150+
"Enables detection of UAR errors in all cases. (reduces code size, "
151+
"but not as much as never). Requires druntime support.")));
152+
124153
SanitizerBits enabledSanitizers = 0;
125154

126155
// Parse sanitizer name passed on commandline and return the corresponding

driver/cl_options_sanitizers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class FuncDeclaration;
2020
namespace llvm {
2121
class raw_ostream;
2222
class StringRef;
23+
enum class AsanDetectStackUseAfterReturnMode;
2324
}
2425

2526
namespace opts {
@@ -37,6 +38,8 @@ enum SanitizerCheck : SanitizerBits {
3738
};
3839
extern SanitizerBits enabledSanitizers;
3940

41+
extern cl::opt<llvm::AsanDetectStackUseAfterReturnMode> fSanitizeAddressUseAfterReturn;
42+
4043
inline bool isAnySanitizerEnabled() { return enabledSanitizers; }
4144
inline bool isSanitizerEnabled(SanitizerBits san) {
4245
return enabledSanitizers & san;

gen/optimizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ static void addAddressSanitizerPasses(ModulePassManager &mpm,
454454
aso.CompileKernel = false;
455455
aso.Recover = false;
456456
aso.UseAfterScope = true;
457-
aso.UseAfterReturn = AsanDetectStackUseAfterReturnMode::Runtime;
457+
aso.UseAfterReturn = opts::fSanitizeAddressUseAfterReturn;
458458

459459
#if LDC_LLVM_VER >= 1600
460460
mpm.addPass(AddressSanitizerPass(aso));

tests/sanitizers/fuzz_asan.d

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
// REQUIRES: Fuzzer, ASan
44

55
// See https://github.com/ldc-developers/ldc/issues/2222 for %disable_fp_elim
6-
// RUN: %ldc -g -fsanitize=address,fuzzer %disable_fp_elim %s -of=%t%exe
6+
// See https://github.com/ldc-developers/ldc/pull/4328 for -fsanitize-address-use-after-return=never
7+
// RUN: %ldc -g -fsanitize=address,fuzzer -fsanitize-address-use-after-return=never %disable_fp_elim %s -of=%t%exe
78
// RUN: not %t%exe 2>&1 | FileCheck %s
89

910
bool FuzzMe(ubyte* data, size_t dataSize)
@@ -12,7 +13,7 @@ bool FuzzMe(ubyte* data, size_t dataSize)
1213
data[0] == 'F' &&
1314
data[1] == 'U' &&
1415
data[2] == 'Z' &&
15-
// CHECK: ERROR: AddressSanitizer: {{stack-buffer-overflow|stack-use-after-return}}
16+
// CHECK: ERROR: AddressSanitizer: stack-buffer-overflow
1617
// CHECK-NEXT: READ of size 1
1718
// CHECK-NEXT: #0 {{.*}} in {{.*fuzz_asan6FuzzMe.*}} {{.*}}fuzz_asan.d:
1819
// FIXME, debug line info is wrong (Github issue #2090). Once fixed, add [[@LINE+1]]

0 commit comments

Comments
 (0)