Skip to content

Commit

Permalink
kasan: rust: Add KASAN smoke test via UAF
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Andrey Konovalov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
[ Applied empty line nit, removed double empty line,
  applied `rustfmt` and formatted crate comment. - Miguel ]
Signed-off-by: Miguel Ojeda <[email protected]>
  • Loading branch information
maurer authored and ojeda committed Sep 16, 2024
1 parent e311740 commit a2f1154
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
8 changes: 7 additions & 1 deletion mm/kasan/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,19 @@ 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
obj-$(CONFIG_KASAN_GENERIC) += init.o generic.o report_generic.o shadow.o quarantine.o
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
6 changes: 6 additions & 0 deletions mm/kasan/kasan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) { }
Expand Down
11 changes: 11 additions & 0 deletions mm/kasan/kasan_test.c → mm/kasan/kasan_test_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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),
{}
};

Expand Down
21 changes: 21 additions & 0 deletions mm/kasan/kasan_test_rust.rs
Original file line number Diff line number Diff line change
@@ -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 }
}

0 comments on commit a2f1154

Please sign in to comment.