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

Debug implementation for XEvent is unsound #123

Open
WaffleLapkin opened this issue Mar 11, 2021 · 0 comments
Open

Debug implementation for XEvent is unsound #123

WaffleLapkin opened this issue Mar 11, 2021 · 0 comments

Comments

@WaffleLapkin
Copy link

The Debug implementation for XEvent assumes that .type_ is set right, but it is public and can be set to any value in safe code.

https://github.com/erlepereira/x11-rs/blob/c4dcb13ae894c761722769088829d5cd7db3fb71/src/xlib.rs#L1042-L1049

This allows, for example, to read uninitialized memory in safe code:

// x11 = "2.18"

fn main() {
    let wrong = x11::xlib::XCirculateEvent { 
        // Wrong tag
        type_: x11::xlib::ButtonPress,
        // All other fields don't matter
        serial: 0,
        send_event: 0,
        display: core::ptr::null_mut(),
        event: 0,
        window: 0,
        place: 0,
    };

    // button event have more fields, so this reads uninitialized memory
    println!("{:?}", x11::xlib::XEvent { circulate: wrong });
}

Example outputs:

XEvent { button: XButtonEvent { type_: 4, serial: 0, send_event: 0, display: 0x0, window: 0, root: 0, subwindow: 0, time: 140436485040640, x: 32, y: 0, x_root: -150365344, y_root: 22003, state: 3937517568, button: 32697, same_screen: -357449728 } }
XEvent { button: XButtonEvent { type_: 4, serial: 0, send_event: 0, display: 0x0, window: 0, root: 0, subwindow: 0, time: 139885648939520, x: 32, y: 0, x_root: -714048672, y_root: 22090, state: 2857230336, button: 32569, same_screen: -1437736960 } }

miri output:

spoiler

error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
   --> /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/num.rs:462:5
    |
462 | /     impl_Display!(
463 | |         i8, u8, i16, u16, i32, u32, i64, u64, usize, isize
464 | |             as u64 via to_u64 named fmt_u64
465 | |     );
    | |______^ using uninitialized data, but this operation requires initialized memory
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

    = note: inside `core::fmt::num::imp::<impl std::fmt::Display for u64>::fmt` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/num.rs:280:38
    = note: inside `core::fmt::num::<impl std::fmt::Debug for u64>::fmt` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/num.rs:191:21
    = note: inside `<&u64 as std::fmt::Debug>::fmt` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:2010:62
    = note: inside closure at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:154:17
    = note: inside `std::result::Result::<(), std::fmt::Error>::and_then::<(), [closure@std::fmt::DebugStruct::field::{closure#0}]>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:704:22
    = note: inside `std::fmt::DebugStruct::field` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:137:23
    = note: inside `<x11::xlib::XButtonEvent as std::fmt::Debug>::fmt` at /home/waffle/.cargo/registry/src/github.com-1ecc6299db9ec823/x11-2.18.2/src/xlib.rs:1181:10
    = note: inside closure at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:154:17
    = note: inside `std::result::Result::<(), std::fmt::Error>::and_then::<(), [closure@std::fmt::DebugStruct::field::{closure#0}]>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:704:22
    = note: inside `std::fmt::DebugStruct::field` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:137:23
    = note: inside `<x11::xlib::XEvent as std::fmt::Debug>::fmt` at /home/waffle/.cargo/registry/src/github.com-1ecc6299db9ec823/x11-2.18.2/src/xlib.rs:1049:24
    = note: inside `std::fmt::write` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:1092:17
    = note: inside `<std::io::StdoutLock as std::io::Write>::write_fmt` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:1567:15
    = note: inside `<&std::io::Stdout as std::io::Write>::write_fmt` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:662:9
    = note: inside `<std::io::Stdout as std::io::Write>::write_fmt` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:636:9
    = note: inside `std::io::stdio::print_to::<std::io::Stdout>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:939:21
    = note: inside `std::io::_print` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:952:5
note: inside `main` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:97:9
   --> src/main.rs:14:5
    |
14  |     println!("{:?}", x11::xlib::XEvent { circulate: wrong });
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: inside `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
    = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:125:18
    = note: inside closure at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:66:18
    = note: inside `std::ops::function::impls::<impl std::ops::FnOnce<()> for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:259:13
    = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
    = note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
    = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
    = note: inside `std::rt::lang_start_internal` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:51:25
    = note: inside `std::rt::lang_start::<()>` at /home/waffle/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:65:5
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

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

No branches or pull requests

2 participants