rustarok icon indicating copy to clipboard operation
rustarok copied to clipboard

unsoundness in write_f32 groups

Open lwz23 opened this issue 11 months ago • 1 comments

I think there exist a unaligned problem in this project, because they are pub function, I assume other mod can control them directly. https://github.com/bbodi/rustarok/blob/7ea7abfa5631f74ad31ce0c2f0f8730c9ef70765/common/src/packets/mod.rs#L167 https://github.com/bbodi/rustarok/blob/7ea7abfa5631f74ad31ce0c2f0f8730c9ef70765/common/src/packets/mod.rs#L179

Poc:

pub struct SocketBuffer {
    buf: [u8; 2048],
    /// pointer at which the OS writes/reads the data during send/recv
    os_pointer: usize,
    /// pointer at which the application writes/reads the data during send/recv
    user_pointer: usize,
}

impl SocketBuffer {
    pub fn write_f32(&mut self, value: f32) {
        unsafe {
            *(self.buf.as_mut_ptr().offset(self.user_pointer as isize) as *mut f32) = value;
        }
        self.user_pointer += 4;
    }
}

fn main() {

    let mut buffer = SocketBuffer {
        buf: [0; 2048],
        os_pointer: 0,
        user_pointer: 1, // unaligned
    };

    buffer.write_f32(42.0);


}

result:

PS E:\Github\lwz> cargo +nightly miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running `C:\Users\ROG\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\bin\cargo-miri.exe runner target\miri\x86_64-pc-windows-msvc\debug\lwz.exe`
warning: field `os_pointer` is never read
 --> src\main.rs:4:5
  |
1 | pub struct SocketBuffer {
  |            ------------ field in this struct
...
4 |     os_pointer: usize,
  |     ^^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

error: Undefined Behavior: accessing memory based on pointer with alignment 1, but alignment 4 is required
  --> src\main.rs:12:13
   |
12 | ...   *(self.buf.as_mut_ptr().offset(self.user_pointer as isize) as *mut f32) = val...
   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required
   |
   = 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: BACKTRACE:
   = note: inside `SocketBuffer::write_f32` at src\main.rs:12:13: 12:92
note: inside `main`
  --> src\main.rs:27:5
   |
27 |     buffer.write_f32(42.0);
   |     ^^^^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error; 1 warning emitted

error: process didn't exit successfully: `C:\Users\ROG\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\bin\cargo-miri.exe runner target\miri\x86_64-pc-windows-msvc\debug\lwz.exe` (exit code: 1)
PS E:\Github\lwz> cargo +nightly miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running `C:\Users\ROG\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\bin\cargo-miri.exe runner target\miri\x86_64-pc-windows-msvc\debug\lwz.exe`
warning: field `os_pointer` is never read
 --> src\main.rs:4:5
  |
1 | pub struct SocketBuffer {
  |            ------------ field in this struct
...
4 |     os_pointer: usize,
  |     ^^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

error: Undefined Behavior: accessing memory based on pointer with alignment 1, but alignment 4 is required
  --> src\main.rs:12:13
   |
12 | ...   *(self.buf.as_mut_ptr().offset(self.user_pointer as isize) as *mut f32) = val...
   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory based on pointer with alignment 1, but alignment 4 is required
   |
   = 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: BACKTRACE:
   = note: inside `SocketBuffer::write_f32` at src\main.rs:12:13: 12:92
note: inside `main`
  --> src\main.rs:26:5
   |
26 |     buffer.write_f32(42.0);
   |     ^^^^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error; 1 warning emitted

error: process didn't exit successfully: `C:\Users\ROG\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\bin\cargo-miri.exe runner target\miri\x86_64-pc-windows-msvc\debug\lwz.exe` (exit code: 1)
PS E:\Github\lwz> 

lwz23 avatar Jan 06 '25 07:01 lwz23

same for https://github.com/bbodi/rustarok/blob/7ea7abfa5631f74ad31ce0c2f0f8730c9ef70765/common/src/packets/mod.rs#L181 https://github.com/bbodi/rustarok/blob/7ea7abfa5631f74ad31ce0c2f0f8730c9ef70765/common/src/packets/mod.rs#L188 https://github.com/bbodi/rustarok/blob/7ea7abfa5631f74ad31ce0c2f0f8730c9ef70765/common/src/packets/mod.rs#L195 https://github.com/bbodi/rustarok/blob/7ea7abfa5631f74ad31ce0c2f0f8730c9ef70765/common/src/packets/mod.rs#L202

lwz23 avatar Jan 06 '25 07:01 lwz23