Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible Null Pointer Dereference Vulnerability #58

Open
ydongyeon opened this issue Oct 13, 2024 · 0 comments
Open

Possible Null Pointer Dereference Vulnerability #58

ydongyeon opened this issue Oct 13, 2024 · 0 comments

Comments

@ydongyeon
Copy link

Summary

An unsafe vulnerability in the vulkan_debug_callback function allows arbitrary memory access when null pointer is provided, potentially triggering undefined behavior.

Details

Hi,

First, I want to extend my gratitude for maintaining this excellent crate. I’ve identified a potential security vulnerability: Null Pointer Dereference.

Environment:

  • OS: Ubuntu 22.04.4 LTS
  • Rust Compiler: rustc 1.83.0-nightly (9c01301c5, 2024-09-05)
  • Cargo: cargo 1.83.0-nightly (c1fa840a8, 2024-08-29)
  • pilka: Latest version (commit d87af8b, 2024-07-08)

Steps to reproduce:

(1) Replace pilka/src/instance.rs with the modified instance.rs file as below.

... // existing codes
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vulkan_debug_callback() {
        let message_severity = vk::DebugUtilsMessageSeverityFlagsEXT::WARNING;

        let message_type = vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION;

        let test_message = std::ffi::CString::new("Validation Warning: [ VUID_Undefined ] Test Message").unwrap();
        
        unsafe {
            vulkan_debug_callback(
                message_severity,
                message_type,
                std::ptr::null_mut(),
                std::ptr::null_mut(),
            );
        }

    }
}

(2) Run the test using the ASan flag.

RUSTFLAGS="-Zsanitizer=address" cargo +nightly test vulkan_debug_callback --target x86_64-unknown-linux-gnu

Details:
// pilka/src/instance.rs

unsafe extern "system" fn vulkan_debug_callback(
    message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
    message_type: vk::DebugUtilsMessageTypeFlagsEXT,
    p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT,
    _user_data: *mut std::os::raw::c_void,
) -> vk::Bool32 {
    let callback_data = &unsafe { *p_callback_data };
    let message = unsafe { CStr::from_ptr(callback_data.p_message) }.to_string_lossy();

    if message.starts_with("Validation Performance Warning") {
    } else if message.starts_with("Validation Warning: [ VUID_Undefined ]") {
        log::warn!("{:?}:\n{:?}: {}\n", message_severity, message_type, message,);
    } else {
        log::error!("{:?}:\n{:?}: {}\n", message_severity, message_type, message,);
    }

    vk::FALSE
}

In this case, the vulcan_debug_callback function uses the unsafe keyword to access memory without performing null pointer checking. Specifically, it directly dereferences a pointer by {*p_callback_data}. This approach violates Rust’s memory safety guarantees, as it can lead to invalid memory access if p_callback_data is given as null pointer.

Actual results :
running 1 test
AddressSanitizer:DEADLYSIGNAL
==1325429==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7ffff7cc4881 bp 0x7ffff4afe0d0 sp 0x7ffff4afd888 T1)
==1325429==The signal is caused by a READ memory access.
==1325429==Hint: address points to the zero page.
#0 0x7ffff7cc4881 in memcpy string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:222
#1 0x55555564228b in __asan_memcpy /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
#2 0x5555556728c1 in pilka::instance::vulkan_debug_callback::hc18903acc478d7ff /home/dy3199/Fuzzing-Test/pilka/src/instance.rs:16:35
#3 0x555555670a42 in pilka::instance::tests::test_vulkan_debug_callback::hadcb06e98d369717 /home/dy3199/Fuzzing-Test/pilka/src/instance.rs:294:13
#4 0x555555670666 in pilka::instance::tests::test_vulkan_debug_callback::$u7b$$u7b$closure$u7d$$u7d$::h7c534bd0a0854d1d /home/dy3199/Fuzzing-Test/pilka/src/instance.rs:286:36
#5 0x555555671605 in core::ops::function::FnOnce::call_once::h4cf2308365054579 /home/dy3199/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
#6 0x5555556b254a in core::ops::function::FnOnce::call_once::h556141b0b8fdbb6d /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/core/src/ops/function.rs:250:5
#7 0x5555556b254a in test::__rust_begin_short_backtrace::h0db03bcef8350635 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:621:18
#8 0x5555556b1e77 in test::run_test_in_process::
$u7b$$u7b$closure$u7d$$u7d$::h2b26e78103d00faf /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:644:60
#9 0x5555556b1e77 in $LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h9b9bdb051f35126f /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/core/src/panic/unwind_safe.rs:272:9
#10 0x5555556b1e77 in std::panicking::try::do_call::he60eac3431009064 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:557:40
#11 0x5555556b1e77 in std::panicking::try::h557550d22ddb3954 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:520:19
#12 0x5555556b1e77 in std::panic::catch_unwind::hdcc5278601cde996 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panic.rs:358:14
#13 0x5555556b1e77 in test::run_test_in_process::h8aa3c0adb7acfe05 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:644:27
#14 0x5555556b1e77 in test::run_test::
$u7b$$u7b$closure$u7d$$u7d$::he4cb7f7454d67ec7 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:565:43
#15 0x555555676093 in test::run_test::$u7b$$u7b$closure$u7d$$u7d$::hbf7c34f88a9b7c99 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:595:41
#16 0x555555676093 in std::sys::backtrace::_rust_begin_short_backtrace::hd1596cbf522e6291 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/sys/backtrace.rs:154:18
#17 0x555555679741 in std::thread::Builder::spawn_unchecked
::
$u7b$$u7b$closure$u7d$$u7d$::$u7b$$u7b$closure$u7d$$u7d$::h1477a43ebce5a9b4 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/thread/mod.rs:521:17
#18 0x555555679741 in $LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::hc950408692c13207 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/core/src/panic/unwind_safe.rs:272:9
#19 0x555555679741 in std::panicking::try::do_call::h6fa8fa2b2d7081fc /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:557:40
#20 0x555555679741 in std::panicking::try::he538ba63cebd8a21 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:520:19
#21 0x555555679741 in std::panic::catch_unwind::h96162f68493eada2 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panic.rs:358:14
#22 0x555555679741 in std::thread::Builder::spawn_unchecked
::
$u7b$$u7b$closure$u7d$$u7d$::he08e8b93402f8ad5 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/thread/mod.rs:520:30
#23 0x555555679741 in core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h3a43bb91522745d7 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/core/src/ops/function.rs:250:5
#24 0x5555556e7fba in _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h8054fe12b89a640e /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/alloc/src/boxed.rs:2454:9
#25 0x5555556e7fba in _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::heda44ff6113dd81b /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/alloc/src/boxed.rs:2454:9
#26 0x5555556e7fba in std::sys::pal::unix::thread::Thread::new::thread_start::h44e9704e75fad799 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/sys/pal/unix/thread.rs:105:17
#27 0x555555642146 in asan_thread_start(void*) /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:239:28
#28 0x7ffff7c94ac2 in start_thread nptl/pthread_create.c:442:8
#29 0x7ffff7d2684f misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

==1325429==Register values:
rax = 0x00007ffff41ff2c0 rbx = 0x00007ffff41ff2c0 rcx = 0x000010007e837e58 rdx = 0x0000000000000060
rdi = 0x00007ffff41ff2c0 rsi = 0x0000000000000000 rbp = 0x00007ffff4afe0d0 rsp = 0x00007ffff4afd888
r8 = 0x0000000000000000 r9 = 0x0000000000000007 r10 = 0xffffffffffffffff r11 = 0x0000000000000000
r12 = 0x0000000000000000 r13 = 0x000000000000001f r14 = 0x0000000000000060 r15 = 0x0000000000000000
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:222 in memcpy
Thread T1 created by T0 here:
#0 0x555555629fe1 in pthread_create /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:250:3
#1 0x5555556e7df1 in std::sys::pal::unix::thread::Thread::new::hb67b1d5b2580523d /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/sys/pal/unix/thread.rs:84:19
#2 0x5555556afe73 in std::thread::Builder::spawn_unchecked_::hc86feaa291a60338 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/thread/mod.rs:560:30
#3 0x5555556afe73 in std::thread::Builder::spawn_unchecked::hc983240132661237 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/thread/mod.rs:441:32
#4 0x5555556afe73 in std::thread::Builder::spawn::h3a197a5d5820ab55 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/thread/mod.rs:374:18
#5 0x5555556afe73 in test::run_test::h88139ddd3d467ad1 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:595:27
#6 0x555555690425 in test::run_tests::h80cc0c21bf0f58b6 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:405:21
#7 0x555555690425 in test::console::run_tests_console::h8c103401cf2149f7 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/console.rs:322:5
#8 0x5555556acf0b in test::test_main::hbfe100dfe8e6cf70 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:138:19
#9 0x5555556addba in test::test_main_static::h2642b7736db7c98a /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/test/src/lib.rs:160:5
#10 0x555555671cc2 in pilka::main::hdb70a84d55054ec8 /home/dy3199/Fuzzing-Test/pilka/src/lib.rs
#11 0x5555556d908f in core::ops::function::impls::$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::ha1f1642b8e9bd74a /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/core/src/ops/function.rs:284:13
#12 0x5555556d908f in std::panicking::try::do_call::hecea85fe7d6edda5 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:557:40
#13 0x5555556d908f in std::panicking::try::h4f8eb6ebee171f35 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:520:19
#14 0x5555556d908f in std::panic::catch_unwind::h77a3b376b0c0e5e5 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panic.rs:358:14
#15 0x5555556d908f in std::rt::lang_start_internal::
$u7b$$u7b$closure$u7d$$u7d$::h24187c45e225a599 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/rt.rs:143:48
#16 0x5555556d908f in std::panicking::try::do_call::hf548e8a6255337a0 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:557:40
#17 0x5555556d908f in std::panicking::try::h147ab63ac654d01d /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panicking.rs:520:19
#18 0x5555556d908f in std::panic::catch_unwind::h67c6eb5eb863d18c /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/panic.rs:358:14
#19 0x5555556d908f in std::rt::lang_start_internal::h84c7f39b990c0649 /rustc/18b1161ec9eeab8927f91405bca0ddf59a4a26c9/library/std/src/rt.rs:143:20
#20 0x555555670488 in std::rt::lang_start::hb7f1b087d0f24dd5 /home/dy3199/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:163:17
#21 0x555555671ced in main (/home/dy3199/Fuzzing-Test/pilka/target/x86_64-unknown-linux-gnu/debug/deps/pilka-7c782527fbf7bbca+0x11dced) (BuildId: 1b59f56f7cdcdde3ca1836335196e850351ab9e0)
==287389==ABORTING

Screenshot 2024-10-13 at 5 54 14 PM

Recommended Patch:
Given the potential memory safety issues, I would suggest: Implementing input validation in vulkan_debug_callback to safely handle unexpected null pointer value.

...
assert!(p_callback_data.is_nonnull());
let callback_data = &unsafe { *p_callback_data };
...

Impact

The vulkan_debug_callback function of the pilka library introduces an unsafe vulnerability by allowing arbitrary memory access without proper null pointer checking. This flaw can lead to undefined behavior. Although exploiting this vulnerability may be challenging, it undermines Rust’s core memory safety guarantees.

Although these bugs may be difficult to exploit in practice, I understand that the Rust community reports such issues to RUSTSEC in an effort to further enhance memory safety. Rust considers these issues critical to memory safety, regardless of whether they have been exploited, and takes proactive measures to either fix or report them. I have included references to similar cases below for your consideration. Therefore, while the potential for exploitation may be low, I believe that eliminating potential memory unsafety in unsafe regions can contribute to strengthening Rust's memory safety.

Panic on overflow in subtraction
RUSTSEC-2023-0078
RUSTSEC-2022-0078
RUSTSEC-2022-0012
RUSTSEC-2021-0122

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant