Add kernel-hwaddress sanitizer

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
Alice Ryhl
2026-02-24 11:10:51 +00:00
parent 85e19b8ce8
commit a197752e88
37 changed files with 345 additions and 22 deletions
@@ -587,6 +587,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
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""#,
@@ -654,7 +655,9 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
Some(sym::memtag) => apply(SanitizerSet::MEMTAG),
Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK),
Some(sym::thread) => apply(SanitizerSet::THREAD),
Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS),
Some(sym::hwaddress) | Some(sym::kernel_hwaddress) => {
apply(SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS)
}
Some(sym::realtime) => match value.value_as_str() {
Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking),
Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking),
@@ -679,6 +682,7 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
sym::shadow_call_stack,
sym::thread,
sym::hwaddress,
sym::kernel_hwaddress,
sym::realtime,
],
);
@@ -120,7 +120,8 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>(
if enabled.contains(SanitizerSet::THREAD) {
attrs.push(llvm::AttributeKind::SanitizeThread.create_attr(cx.llcx));
}
if enabled.contains(SanitizerSet::HWADDRESS) {
if enabled.contains(SanitizerSet::HWADDRESS) || enabled.contains(SanitizerSet::KERNELHWADDRESS)
{
attrs.push(llvm::AttributeKind::SanitizeHWAddress.create_attr(cx.llcx));
}
if enabled.contains(SanitizerSet::SHADOWCALLSTACK) {
@@ -652,6 +652,10 @@ pub(crate) unsafe fn llvm_optimize(
sanitize_kernel_address_recover: config
.sanitizer_recover
.contains(SanitizerSet::KERNELADDRESS),
sanitize_kernel_hwaddress: config.sanitizer.contains(SanitizerSet::KERNELHWADDRESS),
sanitize_kernel_hwaddress_recover: config
.sanitizer_recover
.contains(SanitizerSet::KERNELHWADDRESS),
})
} else {
None
+6 -2
View File
@@ -210,10 +210,14 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
}
pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) {
if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS)
|| attrs.sanitizers.disabled.contains(SanitizerSet::KERNELADDRESS)
{
unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) };
}
if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) {
if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS)
|| attrs.sanitizers.disabled.contains(SanitizerSet::KERNELHWADDRESS)
{
unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) };
}
}
@@ -464,6 +464,8 @@ pub(crate) struct SanitizerOptions {
pub sanitize_hwaddress_recover: bool,
pub sanitize_kernel_address: bool,
pub sanitize_kernel_address_recover: bool,
pub sanitize_kernel_hwaddress: bool,
pub sanitize_kernel_hwaddress_recover: bool,
}
/// LLVMRustRelocModel
@@ -1341,6 +1341,7 @@ fn add_sanitizer_libraries(
if sanitizer.contains(SanitizerSet::LEAK)
&& !sanitizer.contains(SanitizerSet::ADDRESS)
&& !sanitizer.contains(SanitizerSet::HWADDRESS)
&& !sanitizer.contains(SanitizerSet::KERNELHWADDRESS)
{
link_sanitizer_runtime(sess, flavor, linker, "lsan");
}
+1 -1
View File
@@ -773,7 +773,7 @@ pub struct BuiltinAttribute {
DuplicatesOk, EncodeCrossCrate::No, effective_target_features, experimental!(force_target_feature)
),
gated!(
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,
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,
EncodeCrossCrate::No, sanitize, experimental!(sanitize),
),
gated!(
@@ -540,6 +540,8 @@ struct LLVMRustSanitizerOptions {
bool SanitizeHWAddressRecover;
bool SanitizeKernelAddress;
bool SanitizeKernelAddressRecover;
bool SanitizeKernelHWAddress;
bool SanitizeKernelHWAddressRecover;
};
extern "C" typedef void (*registerEnzymeAndPassPipelineFn)(
@@ -767,13 +769,15 @@ extern "C" LLVMRustResult LLVMRustOptimize(
!TM->getTargetTriple().isOSWindows()));
});
}
if (SanitizerOptions->SanitizeHWAddress) {
if (SanitizerOptions->SanitizeHWAddress ||
SanitizerOptions->SanitizeKernelHWAddress) {
OptimizerLastEPCallbacks.push_back(
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level,
ThinOrFullLTOPhase phase) {
HWAddressSanitizerOptions opts(
/*CompileKernel=*/false,
SanitizerOptions->SanitizeHWAddressRecover,
SanitizerOptions->SanitizeKernelHWAddress,
SanitizerOptions->SanitizeHWAddressRecover ||
SanitizerOptions->SanitizeKernelHWAddressRecover,
/*DisableOptimization=*/false);
MPM.addPass(HWAddressSanitizerPass(opts));
});
+4
View File
@@ -229,6 +229,10 @@ macro_rules! ins_sym {
if s == SanitizerSet::KERNELADDRESS {
s = SanitizerSet::ADDRESS;
}
// KHWASAN is still HWASAN under the hood, so it uses the same attribute.
if s == SanitizerSet::KERNELHWADDRESS {
s = SanitizerSet::HWADDRESS;
}
ins_str!(sym::sanitize, &s.to_string());
}
+3 -1
View File
@@ -106,6 +106,7 @@ pub(super) fn sanitizer(l: &TargetModifier, r: Option<&TargetModifier>) -> bool
| SanitizerSet::SHADOWCALLSTACK
| SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS
| SanitizerSet::SAFESTACK
| SanitizerSet::DATAFLOW;
@@ -810,7 +811,7 @@ mod desc {
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)";
pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy;
pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
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'";
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'";
pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
pub(crate) const parse_cfguard: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -1252,6 +1253,7 @@ pub(crate) fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool
"dataflow" => SanitizerSet::DATAFLOW,
"kcfi" => SanitizerSet::KCFI,
"kernel-address" => SanitizerSet::KERNELADDRESS,
"kernel-hwaddress" => SanitizerSet::KERNELHWADDRESS,
"leak" => SanitizerSet::LEAK,
"memory" => SanitizerSet::MEMORY,
"memtag" => SanitizerSet::MEMTAG,
+1 -1
View File
@@ -529,7 +529,7 @@ pub fn emit_lifetime_markers(&self) -> bool {
// AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs.
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
|| self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
|| self.sanitizers().intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS)
}
pub fn diagnostic_width(&self) -> usize {
+1
View File
@@ -1115,6 +1115,7 @@
iterator_collect_fn,
kcfi,
kernel_address,
kernel_hwaddress,
keylocker_x86,
keyword,
kind,
+14 -3
View File
@@ -1175,9 +1175,10 @@ impl SanitizerSet: u16 {
const SHADOWCALLSTACK = 1 << 7;
const KCFI = 1 << 8;
const KERNELADDRESS = 1 << 9;
const SAFESTACK = 1 << 10;
const DATAFLOW = 1 << 11;
const REALTIME = 1 << 12;
const KERNELHWADDRESS = 1 << 10;
const SAFESTACK = 1 << 11;
const DATAFLOW = 1 << 12;
const REALTIME = 1 << 13;
}
}
rustc_data_structures::external_bitflags_debug! { SanitizerSet }
@@ -1191,24 +1192,32 @@ impl SanitizerSet {
(SanitizerSet::ADDRESS, SanitizerSet::HWADDRESS),
(SanitizerSet::ADDRESS, SanitizerSet::MEMTAG),
(SanitizerSet::ADDRESS, SanitizerSet::KERNELADDRESS),
(SanitizerSet::ADDRESS, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::ADDRESS, SanitizerSet::SAFESTACK),
(SanitizerSet::LEAK, SanitizerSet::MEMORY),
(SanitizerSet::LEAK, SanitizerSet::THREAD),
(SanitizerSet::LEAK, SanitizerSet::KERNELADDRESS),
(SanitizerSet::LEAK, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::LEAK, SanitizerSet::SAFESTACK),
(SanitizerSet::MEMORY, SanitizerSet::THREAD),
(SanitizerSet::MEMORY, SanitizerSet::HWADDRESS),
(SanitizerSet::MEMORY, SanitizerSet::KERNELADDRESS),
(SanitizerSet::MEMORY, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::MEMORY, SanitizerSet::SAFESTACK),
(SanitizerSet::THREAD, SanitizerSet::HWADDRESS),
(SanitizerSet::THREAD, SanitizerSet::KERNELADDRESS),
(SanitizerSet::THREAD, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::THREAD, SanitizerSet::SAFESTACK),
(SanitizerSet::HWADDRESS, SanitizerSet::MEMTAG),
(SanitizerSet::HWADDRESS, SanitizerSet::KERNELADDRESS),
(SanitizerSet::HWADDRESS, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::HWADDRESS, SanitizerSet::SAFESTACK),
(SanitizerSet::CFI, SanitizerSet::KCFI),
(SanitizerSet::MEMTAG, SanitizerSet::KERNELADDRESS),
(SanitizerSet::MEMTAG, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::KERNELADDRESS, SanitizerSet::KERNELHWADDRESS),
(SanitizerSet::KERNELADDRESS, SanitizerSet::SAFESTACK),
(SanitizerSet::KERNELHWADDRESS, SanitizerSet::SAFESTACK),
];
/// Return sanitizer's name
@@ -1221,6 +1230,7 @@ pub fn as_str(self) -> Option<&'static str> {
SanitizerSet::DATAFLOW => "dataflow",
SanitizerSet::KCFI => "kcfi",
SanitizerSet::KERNELADDRESS => "kernel-address",
SanitizerSet::KERNELHWADDRESS => "kernel-hwaddress",
SanitizerSet::LEAK => "leak",
SanitizerSet::MEMORY => "memory",
SanitizerSet::MEMTAG => "memtag",
@@ -1266,6 +1276,7 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
"dataflow" => SanitizerSet::DATAFLOW,
"kcfi" => SanitizerSet::KCFI,
"kernel-address" => SanitizerSet::KERNELADDRESS,
"kernel-hwaddress" => SanitizerSet::KERNELHWADDRESS,
"leak" => SanitizerSet::LEAK,
"memory" => SanitizerSet::MEMORY,
"memtag" => SanitizerSet::MEMTAG,
@@ -22,7 +22,9 @@ pub(crate) fn target() -> Target {
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
stack_probes: StackProbeType::Inline,
panic_strategy: PanicStrategy::Abort,
endian: Endian::Big,
@@ -21,7 +21,9 @@ pub(crate) fn target() -> Target {
&["--fix-cortex-a53-843419"],
),
features: "+v8a,+strict-align,+neon".into(),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
@@ -21,7 +21,9 @@ pub(crate) fn target() -> Target {
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
stack_probes: StackProbeType::Inline,
panic_strategy: PanicStrategy::Abort,
default_uwtable: true,
@@ -21,7 +21,9 @@ pub(crate) fn target() -> Target {
&["--fix-cortex-a53-843419"],
),
features: "+v8a,+strict-align,+neon".into(),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
@@ -8,7 +8,9 @@ pub(crate) fn target() -> Target {
// based off the aarch64-unknown-none target at time of addition
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
@@ -12,7 +12,9 @@ pub(crate) fn target() -> Target {
relocation_model: RelocModel::Static,
disable_redzone: true,
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KCFI
| SanitizerSet::KERNELADDRESS
| SanitizerSet::KERNELHWADDRESS,
stack_probes: StackProbeType::Inline,
panic_strategy: PanicStrategy::Abort,
default_uwtable: true,
+1
View File
@@ -168,6 +168,7 @@ pub enum Sanitizer {
Dataflow,
Kcfi,
KernelAddress,
KernelHwaddress,
Leak,
Memory,
Memtag,
@@ -179,6 +179,7 @@
"needs-sanitizer-hwaddress",
"needs-sanitizer-kasan",
"needs-sanitizer-kcfi",
"needs-sanitizer-khwasan",
"needs-sanitizer-leak",
"needs-sanitizer-memory",
"needs-sanitizer-memtag",
@@ -46,6 +46,11 @@ pub(super) fn handle_needs(
condition: cache.sanitizer_kasan,
ignore_reason: "ignored on targets without kernel address sanitizer",
},
Need {
name: "needs-sanitizer-khwasan",
condition: cache.sanitizer_khwasan,
ignore_reason: "ignored on targets without kernel hardware-assisted address sanitizer",
},
Need {
name: "needs-sanitizer-leak",
condition: cache.sanitizer_leak,
@@ -332,6 +337,7 @@ pub(super) struct CachedNeedsConditions {
sanitizer_dataflow: bool,
sanitizer_kcfi: bool,
sanitizer_kasan: bool,
sanitizer_khwasan: bool,
sanitizer_leak: bool,
sanitizer_memory: bool,
sanitizer_thread: bool,
@@ -359,6 +365,7 @@ pub(super) fn load(config: &Config) -> Self {
sanitizer_dataflow: sanitizers.contains(&Sanitizer::Dataflow),
sanitizer_kcfi: sanitizers.contains(&Sanitizer::Kcfi),
sanitizer_kasan: sanitizers.contains(&Sanitizer::KernelAddress),
sanitizer_khwasan: sanitizers.contains(&Sanitizer::KernelHwaddress),
sanitizer_leak: sanitizers.contains(&Sanitizer::Leak),
sanitizer_memory: sanitizers.contains(&Sanitizer::Memory),
sanitizer_thread: sanitizers.contains(&Sanitizer::Thread),
@@ -0,0 +1,29 @@
// Verifies that HWASAN and KHWASAN emit different assembly instrumentation on AArch64.
//
//@ add-minicore
//@ assembly-output: emit-asm
//@ revisions: hwasan khwasan
//@[hwasan] compile-flags: --target aarch64-unknown-linux-gnu -Zsanitizer=hwaddress
//@[khwasan] compile-flags: --target aarch64-unknown-none -Zsanitizer=kernel-hwaddress
//@ compile-flags: -Copt-level=1
#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]
extern crate minicore;
// hwasan-LABEL: test:
// hwasan: adrp x{{[0-9]+}}, :gottprel:__hwasan_tls
// hwasan: mrs x{{[0-9]+}}, TPIDR_EL0
// hwasan: bl __hwasan_check_x0_0_short_v2
// khwasan-LABEL: test:
// khwasan-NOT: __hwasan_tls
// khwasan: orr x{{[0-9]+}}, x0, #0xff00000000000000
// khwasan: bl __hwasan_check_x0_67043328_fixed_0_short_v2
#[no_mangle]
pub fn test(b: &mut u8) -> u8 {
*b
}
@@ -0,0 +1,27 @@
// Verifies that HWASAN and KHWASAN emit different instrumentation.
//
//@ add-minicore
//@ revisions: hwasan khwasan
//@[hwasan] compile-flags: --target aarch64-unknown-linux-gnu -Zsanitizer=hwaddress
//@[khwasan] compile-flags: --target aarch64-unknown-none -Zsanitizer=kernel-hwaddress
//@ compile-flags: -Copt-level=0
#![crate_type = "lib"]
#![feature(no_core, lang_items, sanitize)]
#![no_core]
extern crate minicore;
// hwasan-LABEL: define {{.*}} @test
// hwasan: @__hwasan_tls
// hwasan: call void @llvm.hwasan.check.memaccess.shortgranules
// hwasan: declare void @__hwasan_init()
// khwasan-LABEL: define {{.*}} @test
// khwasan-NOT: @__hwasan_init
// khwasan: @__hwasan_tls
// khwasan: call void @llvm.hwasan.check.memaccess.shortgranules
#[no_mangle]
pub fn test(b: &mut u8) -> u8 {
*b
}
@@ -0,0 +1,33 @@
// Verifies that KernelAddressSanitizer recovery mode can be enabled
// with -Zsanitizer-recover=kernel-address.
//
//@ add-minicore
//@ revisions: KASAN KASAN-RECOVER
//@ compile-flags: -Copt-level=0
//@[KASAN] compile-flags: -Zsanitizer=kernel-address --target x86_64-unknown-none
//@[KASAN] needs-llvm-components: x86
//@[KASAN-RECOVER] compile-flags: -Zsanitizer=kernel-address
//@[KASAN-RECOVER] compile-flags: -Zsanitizer-recover=kernel-address --target x86_64-unknown-none
//@[KASAN-RECOVER] needs-llvm-components: x86
#![feature(no_core, sanitize, lang_items)]
#![no_core]
#![crate_type = "lib"]
extern crate minicore;
use minicore::*;
// KASAN-LABEL: define{{.*}}@penguin(
// KASAN: call void @__asan_report_load4(
// KASAN: unreachable
// KASAN: }
// KASAN-RECOVER-LABEL: define{{.*}}@penguin(
// KASAN-RECOVER: call void @__asan_report_load4_noabort(
// KASAN-RECOVER-NOT: unreachable
// KASAN-RECOVER: }
#[no_mangle]
pub unsafe fn penguin(p: *mut i32) -> i32 {
*p
}
@@ -0,0 +1,21 @@
// Verifies that `-Zsanitizer=kernel-hwaddress` enables lifetime markers.
//@ add-minicore
//@ compile-flags: -Zsanitizer=kernel-hwaddress -Copt-level=0
//@ revisions: aarch64
//@[aarch64] compile-flags: --target aarch64-unknown-none
//@[aarch64] needs-llvm-components: aarch64
#![crate_type = "rlib"]
#![feature(no_core, lang_items)]
#![no_core]
extern crate minicore;
use minicore::*;
// CHECK-LABEL: ; khwasan_lifetime_markers::test
// CHECK: call void @llvm.lifetime.start
// CHECK: call void @llvm.lifetime.end
pub fn test() {
let _x = [0u8; 10];
}
@@ -0,0 +1,37 @@
// Verifies that KernelHWAddressSanitizer recovery mode can be enabled
// with -Zsanitizer-recover=kernel-hwaddress.
//
//@ add-minicore
//@[KHWASAN] needs-llvm-components: aarch64
//@[KHWASAN-RECOVER] needs-llvm-components: aarch64
//@ revisions: KHWASAN KHWASAN-RECOVER
//@ no-prefer-dynamic
//@ compile-flags: -Copt-level=0
//@[KHWASAN] compile-flags: -Zsanitizer=kernel-hwaddress --target aarch64-unknown-none
//@[KHWASAN-RECOVER] compile-flags: -Zsanitizer=kernel-hwaddress
//@[KHWASAN-RECOVER] compile-flags: -Zsanitizer-recover=kernel-hwaddress
//@[KHWASAN-RECOVER] compile-flags: --target aarch64-unknown-none
#![feature(no_core, sanitize, lang_items)]
#![no_core]
#![crate_type = "lib"]
extern crate minicore;
use minicore::*;
// KHWASAN-LABEL: define{{.*}}@penguin(
// KHWASAN: call void @llvm.hwasan.check.memaccess
// KHWASAN: ret i32
// KHWASAN: }
// KHWASAN: declare void @__hwasan_load4(i64)
// KHWASAN-RECOVER-LABEL: define{{.*}}@penguin(
// KHWASAN-RECOVER: call void asm sideeffect "brk #2338", "{x0}"(i64 %{{[0-9]+}})
// KHWASAN-RECOVER-NOT: unreachable
// KHWASAN-RECOVER: }
// KHWASAN-RECOVER: declare void @__hwasan_load4_noabort(i64)
#[no_mangle]
pub unsafe fn penguin(p: *mut i32) -> i32 {
*p
}
@@ -0,0 +1,38 @@
// Verifies that the `#[sanitize(hwaddress = "off")]` attribute also turns off
// the kernel hardware-assisted address sanitizer.
//
//@ add-minicore
//@ compile-flags: -Zsanitizer=kernel-hwaddress -Ctarget-feature=-crt-static -Copt-level=0
//@ revisions: aarch64 aarch64v8r
//@[aarch64] compile-flags: --target aarch64-unknown-none
//@[aarch64] needs-llvm-components: aarch64
//@[aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@[aarch64v8r] needs-llvm-components: aarch64
#![crate_type = "rlib"]
#![feature(no_core, sanitize, lang_items)]
#![no_core]
extern crate minicore;
use minicore::*;
// CHECK-NOT: sanitize_hwaddress
// CHECK-LABEL: define {{.*}} @unsanitized
// CHECK: start:
// CHECK-NOT: call void @llvm.hwasan.check.memaccess
// CHECK: }
#[sanitize(hwaddress = "off")]
#[no_mangle]
pub fn unsanitized(b: &mut u8) -> u8 {
*b
}
// CHECK: sanitize_hwaddress
// CHECK-LABEL: define {{.*}} @sanitized
// CHECK: start:
// CHECK: call void @llvm.hwasan.check.memaccess
// CHECK: }
#[no_mangle]
pub fn sanitized(b: &mut u8) -> u8 {
*b
}
@@ -0,0 +1,31 @@
// Verifies that the `#[sanitize(kernel_hwaddress = "off")]` attribute also turns off
// the hardware-assisted address sanitizer.
//
//@ needs-sanitizer-hwaddress
//@ compile-flags: -Cunsafe-allow-abi-mismatch=sanitizer
//@ compile-flags: -Ctarget-feature=-crt-static
//@ compile-flags: -Zsanitizer=hwaddress -Copt-level=0
#![crate_type = "lib"]
#![feature(sanitize)]
// CHECK-NOT: sanitize_hwaddress
// CHECK-LABEL: define {{.*}} @unsanitized
// CHECK: start:
// CHECK-NOT: call void @llvm.hwasan.check.memaccess
// CHECK: }
#[sanitize(kernel_hwaddress = "off")]
#[no_mangle]
pub fn unsanitized(b: &mut u8) -> u8 {
*b
}
// CHECK: sanitize_hwaddress
// CHECK-LABEL: define {{.*}} @sanitized
// CHECK: start:
// CHECK: call void @llvm.hwasan.check.memaccess
// CHECK: }
#[no_mangle]
pub fn sanitized(b: &mut u8) -> u8 {
*b
}
@@ -5,7 +5,7 @@
//@ needs-sanitizer-memory
//@ revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER MSAN-RECOVER-LTO
//@ no-prefer-dynamic
//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
//@ compile-flags: -Cunsafe-allow-abi-mismatch=sanitizer
//@ compile-flags: -Ctarget-feature=-crt-static
//@[ASAN] compile-flags: -Zsanitizer=address -Copt-level=0
//@[ASAN-RECOVER] compile-flags: -Zsanitizer=address -Zsanitizer-recover=address -Copt-level=0
+1 -1
View File
@@ -120,7 +120,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | sanitize = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `realtime`, `safestack`, `shadow-call-stack`, and `thread`
= note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `kernel-hwaddress`, `leak`, `memory`, `memtag`, `realtime`, `safestack`, `shadow-call-stack`, and `thread`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -4,7 +4,7 @@ error[E0539]: malformed `sanitize` attribute input
LL | #[sanitize(brontosaurus = "off")]
| ^^^^^^^^^^^------------^^^^^^^^^^
| |
| valid arguments are "address", "kernel_address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress" or "realtime"
| valid arguments are "address", "kernel_address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress", "kernel_hwaddress" or "realtime"
error: multiple `sanitize` attributes
--> $DIR/invalid-sanitize.rs:7:1
+22
View File
@@ -0,0 +1,22 @@
// Verifies that when compiling with -Zsanitizer=kernel-hwaddress,
// the `#[cfg(sanitize = "hwaddress")]` attribute is configured.
//@ add-minicore
//@ check-pass
//@ compile-flags: -Zsanitizer=kernel-hwaddress
//@ revisions: aarch64
//@[aarch64] compile-flags: --target aarch64-unknown-none
//@[aarch64] needs-llvm-components: aarch64
//@ ignore-backends: gcc
#![crate_type = "rlib"]
#![feature(cfg_sanitize, no_core)]
#![no_core]
extern crate minicore;
use minicore::*;
const _: fn() -> () = main;
#[cfg(sanitize = "hwaddress")]
fn main() {}
@@ -0,0 +1,9 @@
//@ compile-flags: -Z sanitizer=kernel-hwaddress -Z sanitizer=kernel-address --target aarch64-unknown-none
//@ needs-llvm-components: aarch64
//@ ignore-backends: gcc
#![feature(no_core)]
#![no_core]
#![no_main]
//~? ERROR `-Zsanitizer=kernel-address` is incompatible with `-Zsanitizer=kernel-hwaddress`
@@ -0,0 +1,4 @@
error: `-Zsanitizer=kernel-address` is incompatible with `-Zsanitizer=kernel-hwaddress`
error: aborting due to 1 previous error
@@ -0,0 +1,9 @@
//@ compile-flags: -Z sanitizer=kernel-hwaddress --target x86_64-unknown-none
//@ needs-llvm-components: x86
//@ ignore-backends: gcc
#![feature(no_core)]
#![no_core]
#![no_main]
//~? ERROR kernel-hwaddress sanitizer is not supported for this target
@@ -0,0 +1,4 @@
error: kernel-hwaddress sanitizer is not supported for this target
error: aborting due to 1 previous error