Skip to content

Commit 58d72ae

Browse files
authored
Rollup merge of rust-lang#81506 - vo4:hwasan, r=nagisa
HWAddressSanitizer support # Motivation Compared to regular ASan, HWASan has a [smaller overhead](https://source.android.com/devices/tech/debug/hwasan). The difference in practice is that HWASan'ed code is more usable, e.g. Android device compiled with HWASan can be used as a daily driver. # Example ``` fn main() { let xs = vec![0, 1, 2, 3]; let _y = unsafe { *xs.as_ptr().offset(4) }; } ``` ``` ==223==ERROR: HWAddressSanitizer: tag-mismatch on address 0xefdeffff0050 at pc 0xaaaad00b3468 READ of size 4 at 0xefdeffff0050 tags: e5/00 (ptr/mem) in thread T0 #0 0xaaaad00b3464 (/root/main+0x53464) #1 0xaaaad00b39b4 (/root/main+0x539b4) #2 0xaaaad00b3dd0 (/root/main+0x53dd0) #3 0xaaaad00b61dc (/root/main+0x561dc) #4 0xaaaad00c0574 (/root/main+0x60574) #5 0xaaaad00b6290 (/root/main+0x56290) #6 0xaaaad00b6170 (/root/main+0x56170) #7 0xaaaad00b3578 (/root/main+0x53578) #8 0xffff81345e70 (/lib64/libc.so.6+0x20e70) #9 0xaaaad0096310 (/root/main+0x36310) [0xefdeffff0040,0xefdeffff0060) is a small allocated heap chunk; size: 32 offset: 16 0xefdeffff0050 is located 0 bytes to the right of 16-byte region [0xefdeffff0040,0xefdeffff0050) allocated here: #0 0xaaaad009bcdc (/root/main+0x3bcdc) #1 0xaaaad00b1eb0 (/root/main+0x51eb0) #2 0xaaaad00b20d4 (/root/main+0x520d4) #3 0xaaaad00b2800 (/root/main+0x52800) #4 0xaaaad00b1cf4 (/root/main+0x51cf4) #5 0xaaaad00b33d4 (/root/main+0x533d4) #6 0xaaaad00b39b4 (/root/main+0x539b4) #7 0xaaaad00b61dc (/root/main+0x561dc) #8 0xaaaad00b3578 (/root/main+0x53578) #9 0xaaaad0096310 (/root/main+0x36310) Thread: T0 0xeffe00002000 stack: [0xffffc0590000,0xffffc0d90000) sz: 8388608 tls: [0xffff81521020,0xffff815217d0) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0xfefcefffef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffef90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffefa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffefb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffefc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffefd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffefe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefcefffeff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0xfefceffff000: a2 a2 05 00 e5 [00] 00 00 00 00 00 00 00 00 00 00 0xfefceffff010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0xfefceffff080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0xfefcefffeff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0xfefceffff000: .. .. c5 .. .. [..] .. .. .. .. .. .. .. .. .. .. 0xfefceffff010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0xaaaad00b3468): x0 e500efdeffff0050 x1 0000000000000004 x2 0000ffffc0d8f5a0 x3 0200efff00000000 x4 0000ffffc0d8f4c0 x5 000000000000004f x6 00000ffffc0d8f36 x7 0000efff00000000 x8 e500efdeffff0050 x9 0200efff00000000 x10 0000000000000000 x11 0200efff00000000 x12 0200effe000006b0 x13 0200effe000006b0 x14 0000000000000008 x15 00000000c00000cf x16 0000aaaad00a0afc x17 0000000000000003 x18 0000000000000001 x19 0000ffffc0d8f718 x20 ba00ffffc0d8f7a0 x21 0000aaaad00962e0 x22 0000000000000000 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000ffffc0d8f650 x30 0000aaaad00b3468 ``` # Comments/Caveats * HWASan is only supported on arm64. * I'm not sure if I should add a feature gate or piggyback on the existing one for sanitizers. * HWASan requires `-C target-feature=+tagged-globals`. That flag should probably be set transparently to the user. Not sure how to go about that. # TODO * Need more tests. * Update documentation. * Fix symbolization. * Integrate with CI
2 parents fc93e26 + 9c34c14 commit 58d72ae

File tree

19 files changed

+187
-14
lines changed

19 files changed

+187
-14
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ pub fn sanitize(cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, llfn: &'ll V
5353
if enabled.contains(SanitizerSet::THREAD) {
5454
llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn);
5555
}
56+
if enabled.contains(SanitizerSet::HWADDRESS) {
57+
llvm::Attribute::SanitizeHWAddress.apply_llfn(Function, llfn);
58+
}
5659
}
5760

5861
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.

compiler/rustc_codegen_llvm/src/back/write.rs

+6
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
440440
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
441441
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
442442
sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD),
443+
sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS),
444+
sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS),
443445
})
444446
} else {
445447
None
@@ -652,6 +654,10 @@ unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static
652654
if config.sanitizer.contains(SanitizerSet::THREAD) {
653655
passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
654656
}
657+
if config.sanitizer.contains(SanitizerSet::HWADDRESS) {
658+
let recover = config.sanitizer_recover.contains(SanitizerSet::HWADDRESS);
659+
passes.push(llvm::LLVMRustCreateHWAddressSanitizerPass(recover));
660+
}
655661
}
656662

657663
pub(crate) fn link(

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pub enum Attribute {
131131
ReturnsTwice = 25,
132132
ReadNone = 26,
133133
InaccessibleMemOnly = 27,
134+
SanitizeHWAddress = 28,
134135
}
135136

136137
/// LLVMIntPredicate
@@ -439,6 +440,8 @@ pub struct SanitizerOptions {
439440
pub sanitize_memory_recover: bool,
440441
pub sanitize_memory_track_origins: c_int,
441442
pub sanitize_thread: bool,
443+
pub sanitize_hwaddress: bool,
444+
pub sanitize_hwaddress_recover: bool,
442445
}
443446

444447
/// LLVMRelocMode
@@ -2128,6 +2131,7 @@ extern "C" {
21282131
Recover: bool,
21292132
) -> &'static mut Pass;
21302133
pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
2134+
pub fn LLVMRustCreateHWAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
21312135
pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
21322136
pub fn LLVMRustAddLastExtensionPasses(
21332137
PMB: &PassManagerBuilder,

compiler/rustc_codegen_ssa/src/back/link.rs

+3
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,9 @@ fn link_sanitizers(sess: &Session, crate_type: CrateType, linker: &mut dyn Linke
893893
if sanitizer.contains(SanitizerSet::THREAD) {
894894
link_sanitizer_runtime(sess, linker, "tsan");
895895
}
896+
if sanitizer.contains(SanitizerSet::HWADDRESS) {
897+
link_sanitizer_runtime(sess, linker, "hwasan");
898+
}
896899
}
897900

898901
fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {

compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ enum LLVMRustAttribute {
8585
ReturnsTwice = 25,
8686
ReadNone = 26,
8787
InaccessibleMemOnly = 27,
88+
SanitizeHWAddress = 28,
8889
};
8990

9091
typedef struct OpaqueRustString *RustStringRef;

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/Support/TimeProfiler.h"
3434
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
3535
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
36+
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
3637
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
3738
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
3839

@@ -133,6 +134,12 @@ extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
133134
return wrap(createThreadSanitizerLegacyPassPass());
134135
}
135136

137+
extern "C" LLVMPassRef LLVMRustCreateHWAddressSanitizerPass(bool Recover) {
138+
const bool CompileKernel = false;
139+
140+
return wrap(createHWAddressSanitizerLegacyPassPass(CompileKernel, Recover));
141+
}
142+
136143
extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
137144
assert(RustPass);
138145
Pass *Pass = unwrap(RustPass);
@@ -722,6 +729,8 @@ struct LLVMRustSanitizerOptions {
722729
bool SanitizeMemoryRecover;
723730
int SanitizeMemoryTrackOrigins;
724731
bool SanitizeThread;
732+
bool SanitizeHWAddress;
733+
bool SanitizeHWAddressRecover;
725734
};
726735

727736
extern "C" void
@@ -886,6 +895,23 @@ LLVMRustOptimizeWithNewPassManager(
886895
/*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
887896
}
888897
);
898+
#endif
899+
}
900+
if (SanitizerOptions->SanitizeHWAddress) {
901+
#if LLVM_VERSION_GE(11, 0)
902+
OptimizerLastEPCallbacks.push_back(
903+
[SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
904+
MPM.addPass(HWAddressSanitizerPass(
905+
/*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
906+
}
907+
);
908+
#else
909+
PipelineStartEPCallbacks.push_back(
910+
[SanitizerOptions](ModulePassManager &MPM) {
911+
MPM.addPass(HWAddressSanitizerPass(
912+
/*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
913+
}
914+
);
889915
#endif
890916
}
891917
}

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
205205
return Attribute::ReadNone;
206206
case InaccessibleMemOnly:
207207
return Attribute::InaccessibleMemOnly;
208+
case SanitizeHWAddress:
209+
return Attribute::SanitizeHWAddress;
208210
}
209211
report_fatal_error("bad AttributeKind");
210212
}

compiler/rustc_session/src/config.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ bitflags! {
4343
const LEAK = 1 << 1;
4444
const MEMORY = 1 << 2;
4545
const THREAD = 1 << 3;
46+
const HWADDRESS = 1 << 4;
4647
}
4748
}
4849

@@ -56,6 +57,7 @@ impl fmt::Display for SanitizerSet {
5657
SanitizerSet::LEAK => "leak",
5758
SanitizerSet::MEMORY => "memory",
5859
SanitizerSet::THREAD => "thread",
60+
SanitizerSet::HWADDRESS => "hwaddress",
5961
_ => panic!("unrecognized sanitizer {:?}", s),
6062
};
6163
if !first {
@@ -73,12 +75,18 @@ impl IntoIterator for SanitizerSet {
7375
type IntoIter = std::vec::IntoIter<SanitizerSet>;
7476

7577
fn into_iter(self) -> Self::IntoIter {
76-
[SanitizerSet::ADDRESS, SanitizerSet::LEAK, SanitizerSet::MEMORY, SanitizerSet::THREAD]
77-
.iter()
78-
.copied()
79-
.filter(|&s| self.contains(s))
80-
.collect::<Vec<_>>()
81-
.into_iter()
78+
[
79+
SanitizerSet::ADDRESS,
80+
SanitizerSet::LEAK,
81+
SanitizerSet::MEMORY,
82+
SanitizerSet::THREAD,
83+
SanitizerSet::HWADDRESS,
84+
]
85+
.iter()
86+
.copied()
87+
.filter(|&s| self.contains(s))
88+
.collect::<Vec<_>>()
89+
.into_iter()
8290
}
8391
}
8492

compiler/rustc_session/src/options.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ macro_rules! options {
253253
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
254254
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
255255
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
256-
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `leak`, `memory` or `thread`";
256+
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `hwaddress`, `leak`, `memory` or `thread`";
257257
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
258258
pub const parse_cfguard: &str =
259259
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -476,6 +476,7 @@ macro_rules! options {
476476
"leak" => SanitizerSet::LEAK,
477477
"memory" => SanitizerSet::MEMORY,
478478
"thread" => SanitizerSet::THREAD,
479+
"hwaddress" => SanitizerSet::HWADDRESS,
479480
_ => return false,
480481
}
481482
}

compiler/rustc_session/src/session.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,8 @@ impl Session {
11261126
self.opts.optimize != config::OptLevel::No
11271127
// AddressSanitizer uses lifetimes to detect use after scope bugs.
11281128
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
1129-
|| self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY)
1129+
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
1130+
|| self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
11301131
}
11311132

11321133
pub fn link_dead_code(&self) -> bool {
@@ -1562,6 +1563,8 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
15621563
"x86_64-unknown-freebsd",
15631564
"x86_64-unknown-linux-gnu",
15641565
];
1566+
const HWASAN_SUPPORTED_TARGETS: &[&str] =
1567+
&["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
15651568

15661569
// Sanitizers can only be used on some tested platforms.
15671570
for s in sess.opts.debugging_opts.sanitizer {
@@ -1570,6 +1573,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
15701573
SanitizerSet::LEAK => LSAN_SUPPORTED_TARGETS,
15711574
SanitizerSet::MEMORY => MSAN_SUPPORTED_TARGETS,
15721575
SanitizerSet::THREAD => TSAN_SUPPORTED_TARGETS,
1576+
SanitizerSet::HWADDRESS => HWASAN_SUPPORTED_TARGETS,
15731577
_ => panic!("unrecognized sanitizer {}", s),
15741578
};
15751579
if !supported_targets.contains(&&*sess.opts.target_triple.triple()) {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ symbols! {
593593
html_no_source,
594594
html_playground_url,
595595
html_root_url,
596+
hwaddress,
596597
i,
597598
i128,
598599
i128_type,

compiler/rustc_typeck/src/collect.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2709,10 +2709,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27092709
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY;
27102710
} else if item.has_name(sym::thread) {
27112711
codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD;
2712+
} else if item.has_name(sym::hwaddress) {
2713+
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS;
27122714
} else {
27132715
tcx.sess
27142716
.struct_span_err(item.span(), "invalid argument for `no_sanitize`")
2715-
.note("expected one of: `address`, `memory` or `thread`")
2717+
.note("expected one of: `address`, `hwaddress`, `memory` or `thread`")
27162718
.emit();
27172719
}
27182720
}

src/bootstrap/configure.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def v(*args):
5151
o("ninja", "llvm.ninja", "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)")
5252
o("locked-deps", "build.locked-deps", "force Cargo.lock to be up to date")
5353
o("vendor", "build.vendor", "enable usage of vendored Rust crates")
54-
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, lsan, msan, tsan)")
54+
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, lsan, msan, tsan, hwasan)")
5555
o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
5656
o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
5757
o("profiler", "build.profiler", "build the profiler runtime")

src/bootstrap/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ fn supported_sanitizers(
804804
"aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
805805
"aarch64-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]),
806806
"aarch64-unknown-linux-gnu" => {
807-
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan"])
807+
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"])
808808
}
809809
"x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
810810
"x86_64-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]),

src/doc/unstable-book/src/compiler-flags/sanitizer.md

+87-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ The tracking issue for this feature is: [#39699](https://github.com/rust-lang/ru
77
This feature allows for use of one of following sanitizers:
88

99
* [AddressSanitizer][clang-asan] a fast memory error detector.
10+
* [HWAddressSanitizer][clang-hwasan] a memory error detector similar to
11+
AddressSanitizer, but based on partial hardware assistance.
1012
* [LeakSanitizer][clang-lsan] a run-time memory leak detector.
1113
* [MemorySanitizer][clang-msan] a detector of uninitialized reads.
1214
* [ThreadSanitizer][clang-tsan] a fast data race detector.
1315

14-
To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=leak`,
15-
`-Zsanitizer=memory` or `-Zsanitizer=thread`.
16+
To enable a sanitizer compile with `-Zsanitizer=address`,
17+
`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory` or
18+
`-Zsanitizer=thread`.
1619

1720
# AddressSanitizer
1821

@@ -174,6 +177,86 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
174177
==39249==ABORTING
175178
```
176179
180+
# HWAddressSanitizer
181+
182+
HWAddressSanitizer is a newer variant of AddressSanitizer that consumes much
183+
less memory.
184+
185+
HWAddressSanitizer is supported on the following targets:
186+
187+
* `aarch64-linux-android`
188+
* `aarch64-unknown-linux-gnu`
189+
190+
HWAddressSanitizer requires `tagged-globals` target feature to instrument
191+
globals. To enable this target feature compile with `-C
192+
target-feature=+tagged-globals`
193+
194+
## Example
195+
196+
Heap buffer overflow:
197+
198+
```rust
199+
fn main() {
200+
let xs = vec![0, 1, 2, 3];
201+
let _y = unsafe { *xs.as_ptr().offset(4) };
202+
}
203+
```
204+
205+
```shell
206+
$ rustc main.rs -Zsanitizer=hwaddress -C target-feature=+tagged-globals -C
207+
linker=aarch64-linux-gnu-gcc -C link-arg=-fuse-ld=lld --target
208+
aarch64-unknown-linux-gnu
209+
```
210+
211+
```shell
212+
$ ./main
213+
==241==ERROR: HWAddressSanitizer: tag-mismatch on address 0xefdeffff0050 at pc 0xaaaae0ae4a98
214+
READ of size 4 at 0xefdeffff0050 tags: 2c/00 (ptr/mem) in thread T0
215+
#0 0xaaaae0ae4a94 (/.../main+0x54a94)
216+
...
217+
218+
[0xefdeffff0040,0xefdeffff0060) is a small allocated heap chunk; size: 32 offset: 16
219+
0xefdeffff0050 is located 0 bytes to the right of 16-byte region [0xefdeffff0040,0xefdeffff0050)
220+
allocated here:
221+
#0 0xaaaae0acb80c (/.../main+0x3b80c)
222+
...
223+
224+
Thread: T0 0xeffe00002000 stack: [0xffffc28ad000,0xffffc30ad000) sz: 8388608 tls: [0xffffaa10a020,0xffffaa10a7d0)
225+
Memory tags around the buggy address (one tag corresponds to 16 bytes):
226+
0xfefcefffef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
227+
0xfefcefffef90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
228+
0xfefcefffefa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
229+
0xfefcefffefb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
230+
0xfefcefffefc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
231+
0xfefcefffefd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
232+
0xfefcefffefe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
233+
0xfefcefffeff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
234+
=>0xfefceffff000: d7 d7 05 00 2c [00] 00 00 00 00 00 00 00 00 00 00
235+
0xfefceffff010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
236+
0xfefceffff020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
237+
0xfefceffff030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
238+
0xfefceffff040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
239+
0xfefceffff050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
240+
0xfefceffff060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
241+
0xfefceffff070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
242+
0xfefceffff080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
243+
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
244+
0xfefcefffeff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
245+
=>0xfefceffff000: .. .. 8c .. .. [..] .. .. .. .. .. .. .. .. .. ..
246+
0xfefceffff010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
247+
See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags
248+
Registers where the failure occurred (pc 0xaaaae0ae4a98):
249+
x0 2c00efdeffff0050 x1 0000000000000004 x2 0000000000000004 x3 0000000000000000
250+
x4 0000fffefc30ac37 x5 000000000000005d x6 00000ffffc30ac37 x7 0000efff00000000
251+
x8 2c00efdeffff0050 x9 0200efff00000000 x10 0000000000000000 x11 0200efff00000000
252+
x12 0200effe00000310 x13 0200effe00000310 x14 0000000000000008 x15 5d00ffffc30ac360
253+
x16 0000aaaae0ad062c x17 0000000000000003 x18 0000000000000001 x19 0000ffffc30ac658
254+
x20 4e00ffffc30ac6e0 x21 0000aaaae0ac5e10 x22 0000000000000000 x23 0000000000000000
255+
x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000
256+
x28 0000000000000000 x29 0000ffffc30ac5a0 x30 0000aaaae0ae4a98
257+
SUMMARY: HWAddressSanitizer: tag-mismatch (/.../main+0x54a94)
258+
```
259+
177260
# LeakSanitizer
178261
179262
LeakSanitizer is run-time memory leak detector.
@@ -321,11 +404,13 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT
321404
322405
* [Sanitizers project page](https://github.com/google/sanitizers/wiki/)
323406
* [AddressSanitizer in Clang][clang-asan]
407+
* [HWAddressSanitizer in Clang][clang-hwasan]
324408
* [LeakSanitizer in Clang][clang-lsan]
325409
* [MemorySanitizer in Clang][clang-msan]
326410
* [ThreadSanitizer in Clang][clang-tsan]
327411
328412
[clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html
413+
[clang-hwasan]: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
329414
[clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html
330415
[clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html
331416
[clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html

src/test/ui/invalid/invalid-no-sanitize.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: invalid argument for `no_sanitize`
44
LL | #[no_sanitize(brontosaurus)]
55
| ^^^^^^^^^^^^
66
|
7-
= note: expected one of: `address`, `memory` or `thread`
7+
= note: expected one of: `address`, `hwaddress`, `memory` or `thread`
88

99
error: aborting due to previous error
1010

0 commit comments

Comments
 (0)