Skip to content

Commit 568aeda

Browse files
committed
MemTagSanitizer Support
Adds support for the LLVM MemTagSanitizer.
1 parent 5569757 commit 568aeda

File tree

15 files changed

+67
-6
lines changed

15 files changed

+67
-6
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ pub fn sanitize<'ll>(cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, llfn: &
5555
if enabled.contains(SanitizerSet::HWADDRESS) {
5656
llvm::Attribute::SanitizeHWAddress.apply_llfn(Function, llfn);
5757
}
58+
if enabled.contains(SanitizerSet::MEMTAG) {
59+
// Check to make sure the mte target feature is actually enabled.
60+
let sess = cx.tcx.sess;
61+
let features = llvm_util::llvm_global_features(sess).join(",");
62+
let mte_feature_enabled = features.rfind("+mte");
63+
let mte_feature_disabled = features.rfind("-mte");
64+
65+
if mte_feature_enabled.is_none() || (mte_feature_disabled > mte_feature_enabled) {
66+
sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`");
67+
}
68+
69+
llvm::Attribute::SanitizeMemTag.apply_llfn(Function, llfn);
70+
}
5871
}
5972

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

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ pub enum Attribute {
190190
StackProtectStrong = 31,
191191
StackProtect = 32,
192192
NoUndef = 33,
193+
SanitizeMemTag = 34,
193194
}
194195

195196
/// LLVMIntPredicate

compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum LLVMRustAttribute {
8383
StackProtectStrong = 31,
8484
StackProtect = 32,
8585
NoUndef = 33,
86+
SanitizeMemTag = 34,
8687
};
8788

8889
typedef struct OpaqueRustString *RustStringRef;

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
226226
return Attribute::StackProtect;
227227
case NoUndef:
228228
return Attribute::NoUndef;
229+
case SanitizeMemTag:
230+
return Attribute::SanitizeMemTag;
229231
}
230232
report_fatal_error("bad AttributeKind");
231233
}

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ mod desc {
376376
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
377377
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
378378
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
379-
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory` or `thread`";
379+
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory`, `memtag`, or `thread`";
380380
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
381381
pub const parse_cfguard: &str =
382382
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -638,6 +638,7 @@ mod parse {
638638
"cfi" => SanitizerSet::CFI,
639639
"leak" => SanitizerSet::LEAK,
640640
"memory" => SanitizerSet::MEMORY,
641+
"memtag" => SanitizerSet::MEMTAG,
641642
"thread" => SanitizerSet::THREAD,
642643
"hwaddress" => SanitizerSet::HWADDRESS,
643644
_ => return false,

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ symbols! {
875875
mem_zeroed,
876876
member_constraints,
877877
memory,
878+
memtag,
878879
message,
879880
meta,
880881
metadata_type,

compiler/rustc_target/src/spec/aarch64_linux_android.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ pub fn target() -> Target {
1414
// As documented in https://developer.android.com/ndk/guides/cpu-features.html
1515
// the neon (ASIMD) and FP must exist on all android aarch64 targets.
1616
features: "+neon,+fp-armv8".to_string(),
17-
supported_sanitizers: SanitizerSet::CFI | SanitizerSet::HWADDRESS,
17+
supported_sanitizers: SanitizerSet::CFI
18+
| SanitizerSet::HWADDRESS
19+
| SanitizerSet::MEMTAG,
1820
..super::android_base::opts()
1921
},
2022
}

compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub fn target() -> Target {
1414
| SanitizerSet::CFI
1515
| SanitizerSet::LEAK
1616
| SanitizerSet::MEMORY
17+
| SanitizerSet::MEMTAG
1718
| SanitizerSet::THREAD
1819
| SanitizerSet::HWADDRESS,
1920
..super::linux_gnu_base::opts()

compiler/rustc_target/src/spec/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ bitflags::bitflags! {
606606
const THREAD = 1 << 3;
607607
const HWADDRESS = 1 << 4;
608608
const CFI = 1 << 5;
609+
const MEMTAG = 1 << 6;
609610
}
610611
}
611612

@@ -619,6 +620,7 @@ impl SanitizerSet {
619620
SanitizerSet::CFI => "cfi",
620621
SanitizerSet::LEAK => "leak",
621622
SanitizerSet::MEMORY => "memory",
623+
SanitizerSet::MEMTAG => "memtag",
622624
SanitizerSet::THREAD => "thread",
623625
SanitizerSet::HWADDRESS => "hwaddress",
624626
_ => return None,
@@ -652,6 +654,7 @@ impl IntoIterator for SanitizerSet {
652654
SanitizerSet::CFI,
653655
SanitizerSet::LEAK,
654656
SanitizerSet::MEMORY,
657+
SanitizerSet::MEMTAG,
655658
SanitizerSet::THREAD,
656659
SanitizerSet::HWADDRESS,
657660
]
@@ -1881,6 +1884,7 @@ impl Target {
18811884
Some("cfi") => SanitizerSet::CFI,
18821885
Some("leak") => SanitizerSet::LEAK,
18831886
Some("memory") => SanitizerSet::MEMORY,
1887+
Some("memtag") => SanitizerSet::MEMTAG,
18841888
Some("thread") => SanitizerSet::THREAD,
18851889
Some("hwaddress") => SanitizerSet::HWADDRESS,
18861890
Some(s) => return Err(format!("unknown sanitizer {}", s)),

compiler/rustc_typeck/src/collect.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3008,14 +3008,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
30083008
codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI;
30093009
} else if item.has_name(sym::memory) {
30103010
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY;
3011+
} else if item.has_name(sym::memtag) {
3012+
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG;
30113013
} else if item.has_name(sym::thread) {
30123014
codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD;
30133015
} else if item.has_name(sym::hwaddress) {
30143016
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS;
30153017
} else {
30163018
tcx.sess
30173019
.struct_span_err(item.span(), "invalid argument for `no_sanitize`")
3018-
.note("expected one of: `address`, `hwaddress`, `memory` or `thread`")
3020+
.note("expected one of: `address`, `cfi`, `hwaddress`, `memory`, `memtag`, or `thread`")
30193021
.emit();
30203022
}
30213023
}

0 commit comments

Comments
 (0)