Open WaffleLapkin opened 3 years ago
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.
Debug
XEvent
.type_
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:
miri
```text 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::::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::::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 `::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 `::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 `::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 `::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::` 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 `>::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::` 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:: 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 + 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 ```
The
Debug
implementation forXEvent
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:
Example outputs:
miri
output:spoiler
```text 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::::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::::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 `::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 `::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 `::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 `::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::` 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 `>::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::` 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:: 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 + 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
```