Skip to content

Commit 0cd8de3

Browse files
Rollup merge of #153049 - Darksonn:kasan-sw-tags, r=fmease
Add `-Zsanitize=kernel-hwaddress` The Linux kernel has a config option called `CONFIG_KASAN_SW_TAGS` that enables `-fsanitize=kernel-hwaddress`. This is not supported by Rust. One slightly awkward detail is that `#[sanitize(address = "off")]` applies to both `-Zsanitize=address` and `-Zsanitize=kernel-address`. Probably it was done this way because both are the same LLVM pass. I replicated this logic here for hwaddress, but it might be undesirable. Note that `#[sanitize(kernel_hwaddress = "off")]` could be supported as an annotation on statics, but since it's also missing for `#[sanitize(hwaddress = "off")]`, I did not add it. MCP: rust-lang/compiler-team#975 Tracking issue: #154171 cc @rcvalle @maurer @ojeda
2 parents 64d5cb6 + 4d86840 commit 0cd8de3

37 files changed

+363
-23
lines changed

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
582582
r#"kernel_address = "on|off""#,
583583
r#"cfi = "on|off""#,
584584
r#"hwaddress = "on|off""#,
585+
r#"kernel_hwaddress = "on|off""#,
585586
r#"kcfi = "on|off""#,
586587
r#"memory = "on|off""#,
587588
r#"memtag = "on|off""#,
@@ -648,7 +649,9 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
648649
Some(sym::memtag) => apply(SanitizerSet::MEMTAG),
649650
Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK),
650651
Some(sym::thread) => apply(SanitizerSet::THREAD),
651-
Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS),
652+
Some(sym::hwaddress) | Some(sym::kernel_hwaddress) => {
653+
apply(SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS)
654+
}
652655
Some(sym::realtime) => match value.value_as_str() {
653656
Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking),
654657
Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking),
@@ -673,6 +676,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
673676
sym::shadow_call_stack,
674677
sym::thread,
675678
sym::hwaddress,
679+
sym::kernel_hwaddress,
676680
sym::realtime,
677681
],
678682
);

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>(
120120
if enabled.contains(SanitizerSet::THREAD) {
121121
attrs.push(llvm::AttributeKind::SanitizeThread.create_attr(cx.llcx));
122122
}
123-
if enabled.contains(SanitizerSet::HWADDRESS) {
123+
if enabled.contains(SanitizerSet::HWADDRESS) || enabled.contains(SanitizerSet::KERNELHWADDRESS)
124+
{
124125
attrs.push(llvm::AttributeKind::SanitizeHWAddress.create_attr(cx.llcx));
125126
}
126127
if enabled.contains(SanitizerSet::SHADOWCALLSTACK) {

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ pub(crate) unsafe fn llvm_optimize(
644644
sanitize_kernel_address_recover: config
645645
.sanitizer_recover
646646
.contains(SanitizerSet::KERNELADDRESS),
647+
sanitize_kernel_hwaddress: config.sanitizer.contains(SanitizerSet::KERNELHWADDRESS),
648+
sanitize_kernel_hwaddress_recover: config
649+
.sanitizer_recover
650+
.contains(SanitizerSet::KERNELHWADDRESS),
647651
})
648652
} else {
649653
None

compiler/rustc_codegen_llvm/src/base.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,14 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
210210
}
211211

212212
pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
213-
if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) {
213+
if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS)
214+
|| attrs.sanitizers.disabled.contains(SanitizerSet::KERNELADDRESS)
215+
{
214216
unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) };
215217
}
216-
if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) {
218+
if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS)
219+
|| attrs.sanitizers.disabled.contains(SanitizerSet::KERNELHWADDRESS)
220+
{
217221
unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) };
218222
}
219223
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ pub(crate) struct SanitizerOptions {
464464
pub sanitize_hwaddress_recover: bool,
465465
pub sanitize_kernel_address: bool,
466466
pub sanitize_kernel_address_recover: bool,
467+
pub sanitize_kernel_hwaddress: bool,
468+
pub sanitize_kernel_hwaddress_recover: bool,
467469
}
468470

469471
/// LLVMRustRelocModel

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
773773
DuplicatesOk, EncodeCrossCrate::No, effective_target_features, experimental!(force_target_feature)
774774
),
775775
gated!(
776-
sanitize, Normal, template!(List: &[r#"address = "on|off""#, r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, r#"kcfi = "on|off""#, r#"memory = "on|off""#, r#"memtag = "on|off""#, r#"shadow_call_stack = "on|off""#, r#"thread = "on|off""#]), ErrorPreceding,
776+
sanitize, Normal, template!(List: &[r#"address = "on|off""#, r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, r#"kernel_hwaddress = "on|off""#, r#"kcfi = "on|off""#, r#"memory = "on|off""#, r#"memtag = "on|off""#, r#"shadow_call_stack = "on|off""#, r#"thread = "on|off""#]), ErrorPreceding,
777777
EncodeCrossCrate::No, sanitize, experimental!(sanitize),
778778
),
779779
gated!(

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ struct LLVMRustSanitizerOptions {
540540
bool SanitizeHWAddressRecover;
541541
bool SanitizeKernelAddress;
542542
bool SanitizeKernelAddressRecover;
543+
bool SanitizeKernelHWAddress;
544+
bool SanitizeKernelHWAddressRecover;
543545
};
544546

545547
extern "C" typedef void (*registerEnzymeAndPassPipelineFn)(
@@ -767,13 +769,15 @@ extern "C" LLVMRustResult LLVMRustOptimize(
767769
!TM->getTargetTriple().isOSWindows()));
768770
});
769771
}
770-
if (SanitizerOptions->SanitizeHWAddress) {
772+
if (SanitizerOptions->SanitizeHWAddress ||
773+
SanitizerOptions->SanitizeKernelHWAddress) {
771774
OptimizerLastEPCallbacks.push_back(
772775
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level,
773776
ThinOrFullLTOPhase phase) {
774777
HWAddressSanitizerOptions opts(
775-
/*CompileKernel=*/false,
776-
SanitizerOptions->SanitizeHWAddressRecover,
778+
SanitizerOptions->SanitizeKernelHWAddress,
779+
SanitizerOptions->SanitizeHWAddressRecover ||
780+
SanitizerOptions->SanitizeKernelHWAddressRecover,
777781
/*DisableOptimization=*/false);
778782
MPM.addPass(HWAddressSanitizerPass(opts));
779783
});

compiler/rustc_session/src/config/cfg.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
229229
if s == SanitizerSet::KERNELADDRESS {
230230
s = SanitizerSet::ADDRESS;
231231
}
232+
// KHWASAN is still HWASAN under the hood, so it uses the same attribute.
233+
if s == SanitizerSet::KERNELHWADDRESS {
234+
s = SanitizerSet::HWADDRESS;
235+
}
232236
ins_str!(sym::sanitize, &s.to_string());
233237
}
234238

compiler/rustc_session/src/options.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ mod target_modifier_consistency_check {
106106
| SanitizerSet::SHADOWCALLSTACK
107107
| SanitizerSet::KCFI
108108
| SanitizerSet::KERNELADDRESS
109+
| SanitizerSet::KERNELHWADDRESS
109110
| SanitizerSet::SAFESTACK
110111
| SanitizerSet::DATAFLOW;
111112

@@ -817,7 +818,7 @@ mod desc {
817818
pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)";
818819
pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy;
819820
pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
820-
pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'";
821+
pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `kernel-hwaddress`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'";
821822
pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
822823
pub(crate) const parse_cfguard: &str =
823824
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -1265,6 +1266,7 @@ pub mod parse {
12651266
"dataflow" => SanitizerSet::DATAFLOW,
12661267
"kcfi" => SanitizerSet::KCFI,
12671268
"kernel-address" => SanitizerSet::KERNELADDRESS,
1269+
"kernel-hwaddress" => SanitizerSet::KERNELHWADDRESS,
12681270
"leak" => SanitizerSet::LEAK,
12691271
"memory" => SanitizerSet::MEMORY,
12701272
"memtag" => SanitizerSet::MEMTAG,

compiler/rustc_session/src/session.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,9 +533,12 @@ impl Session {
533533
pub fn emit_lifetime_markers(&self) -> bool {
534534
self.opts.optimize != config::OptLevel::No
535535
// AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs.
536+
//
536537
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
537-
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
538-
|| self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
538+
//
539+
// HWAddressSanitizer and KernelHWAddressSanitizer will use lifetimes to detect use after
540+
// scope bugs in the future.
541+
|| self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS)
539542
}
540543

541544
pub fn diagnostic_width(&self) -> usize {

0 commit comments

Comments
 (0)