mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
kasan: rust: Add KASAN smoke test via UAF
Adds a smoke test to ensure that KASAN in Rust is actually detecting a Rust-native UAF. There is significant room to expand this test suite, but this will at least ensure that flags are having the intended effect. The rename from kasan_test.c to kasan_test_c.c is in order to allow the single kasan_test.ko test suite to contain both a .o file produced by the C compiler and one produced by rustc. Signed-off-by: Matthew Maurer <mmaurer@google.com> Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> Link: https://lore.kernel.org/r/20240820194910.187826-5-mmaurer@google.com [ Applied empty line nit, removed double empty line, applied `rustfmt` and formatted crate comment. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
e3117404b4
commit
a2f1154705
@ -44,7 +44,8 @@ ifndef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
|
||||
CFLAGS_KASAN_TEST += -fno-builtin
|
||||
endif
|
||||
|
||||
CFLAGS_kasan_test.o := $(CFLAGS_KASAN_TEST)
|
||||
CFLAGS_kasan_test_c.o := $(CFLAGS_KASAN_TEST)
|
||||
RUSTFLAGS_kasan_test_rust.o := $(RUSTFLAGS_KASAN)
|
||||
CFLAGS_kasan_test_module.o := $(CFLAGS_KASAN_TEST)
|
||||
|
||||
obj-y := common.o report.o
|
||||
@ -52,5 +53,10 @@ obj-$(CONFIG_KASAN_GENERIC) += init.o generic.o report_generic.o shadow.o quaran
|
||||
obj-$(CONFIG_KASAN_HW_TAGS) += hw_tags.o report_hw_tags.o tags.o report_tags.o
|
||||
obj-$(CONFIG_KASAN_SW_TAGS) += init.o report_sw_tags.o shadow.o sw_tags.o tags.o report_tags.o
|
||||
|
||||
kasan_test-objs := kasan_test_c.o
|
||||
ifdef CONFIG_RUST
|
||||
kasan_test-objs += kasan_test_rust.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_KASAN_KUNIT_TEST) += kasan_test.o
|
||||
obj-$(CONFIG_KASAN_MODULE_TEST) += kasan_test_module.o
|
||||
|
@ -555,6 +555,12 @@ static inline bool kasan_arch_is_ready(void) { return true; }
|
||||
void kasan_kunit_test_suite_start(void);
|
||||
void kasan_kunit_test_suite_end(void);
|
||||
|
||||
#ifdef CONFIG_RUST
|
||||
char kasan_test_rust_uaf(void);
|
||||
#else
|
||||
static inline char kasan_test_rust_uaf(void) { return '\0'; }
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_KASAN_KUNIT_TEST */
|
||||
|
||||
static inline void kasan_kunit_test_suite_start(void) { }
|
||||
|
@ -1899,6 +1899,16 @@ static void match_all_mem_tag(struct kunit *test)
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that Rust performing a use-after-free using `unsafe` is detected.
|
||||
* This is a smoke test to make sure that Rust is being sanitized properly.
|
||||
*/
|
||||
static void rust_uaf(struct kunit *test)
|
||||
{
|
||||
KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_RUST);
|
||||
KUNIT_EXPECT_KASAN_FAIL(test, kasan_test_rust_uaf());
|
||||
}
|
||||
|
||||
static struct kunit_case kasan_kunit_test_cases[] = {
|
||||
KUNIT_CASE(kmalloc_oob_right),
|
||||
KUNIT_CASE(kmalloc_oob_left),
|
||||
@ -1971,6 +1981,7 @@ static struct kunit_case kasan_kunit_test_cases[] = {
|
||||
KUNIT_CASE(match_all_not_assigned),
|
||||
KUNIT_CASE(match_all_ptr_tag),
|
||||
KUNIT_CASE(match_all_mem_tag),
|
||||
KUNIT_CASE(rust_uaf),
|
||||
{}
|
||||
};
|
||||
|
21
mm/kasan/kasan_test_rust.rs
Normal file
21
mm/kasan/kasan_test_rust.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
//! Helper crate for KASAN testing.
|
||||
//!
|
||||
//! Provides behavior to check the sanitization of Rust code.
|
||||
|
||||
use core::ptr::addr_of_mut;
|
||||
use kernel::prelude::*;
|
||||
|
||||
/// Trivial UAF - allocate a big vector, grab a pointer partway through,
|
||||
/// drop the vector, and touch it.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kasan_test_rust_uaf() -> u8 {
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
for _ in 0..4096 {
|
||||
v.push(0x42, GFP_KERNEL).unwrap();
|
||||
}
|
||||
let ptr: *mut u8 = addr_of_mut!(v[2048]);
|
||||
drop(v);
|
||||
unsafe { *ptr }
|
||||
}
|
Loading…
Reference in New Issue
Block a user