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

misaligned pointer dereference #9

Open
multimeric opened this issue Aug 6, 2024 · 2 comments
Open

misaligned pointer dereference #9

multimeric opened this issue Aug 6, 2024 · 2 comments

Comments

@multimeric
Copy link

When I run the example code, I get:

misaligned pointer dereference: address must be a multiple of 0x8 but is 0x567953308bf4

Backtrace:

stack backtrace:
   0: rust_begin_unwind
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_nounwind_fmt::runtime
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/core/src/panicking.rs:110:18
   2: core::panicking::panic_nounwind_fmt
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/core/src/panicking.rs:120:5
   3: core::panicking::panic_misaligned_pointer_dereference
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/core/src/panicking.rs:287:5
   4: cnproc::parse_msg
             at /home/migwell/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cnproc-0.2.1/src/lib.rs:204:23
   5: cnproc::PidMonitor::get_events
             at /home/migwell/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cnproc-0.2.1/src/lib.rs:167:54
   6: cnproc::PidMonitor::recv
             at /home/migwell/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cnproc-0.2.1/src/lib.rs:186:19
   7: cnproc_monitor::main
             at ./src/main.rs:4:15
   8: core::ops::function::FnOnce::call_once
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/core/src/ops/function.rs:250:5

I guess this has something to do with alignment of the C structs, and my system happens to hit an edge case. In my own <linux/connector.h>, I have:

struct proc_event {
        enum proc_cn_event what;
        __u32 cpu;
        __u64 __attribute__((aligned(8))) timestamp_ns;
       union { ... }
}

However the bindgen doesn't seem to capture this:

cnproc-rs/src/binding.rs

Lines 1072 to 1079 in 3d8f058

#[repr(C)]
#[derive(Copy, Clone)]
pub struct proc_event {
pub what: proc_event_what,
pub cpu: __u32,
pub timestamp_ns: __u64,
pub event_data: proc_event__bindgen_ty_1,
}

@rustybrooks
Copy link

rustybrooks commented Oct 12, 2024

I get this also. This is a new check in rust that was previous undefined behavior, I think. Newly released in 1.7

I don't know a lot about it but it seems like one way to solve the problem is using read_unaligned
https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html

I believe that in the function with the problem, you could possibly replace the *proc_ev with proc_ev.read_unaligned()?

I might try this if I get a minute and submit a PR

unsafe fn parse_msg(header: *const nlmsghdr) -> Option<PidEvent> {
    let msg = (header as usize + nlmsg_length(0)) as *const cn_msg;
    if (*msg).id.idx != binding::CN_IDX_PROC || (*msg).id.val != binding::CN_VAL_PROC {
        return None;
    };
    let proc_ev = (*msg).data.as_ptr() as *const binding::proc_event;
    match (*proc_ev).what {
        binding::PROC_EVENT_FORK => {
            let pid = (*proc_ev).event_data.fork.child_pid;
            Some(PidEvent::Fork(pid))
        }
        binding::PROC_EVENT_EXEC => {
            let pid = (*proc_ev).event_data.exec.process_pid;
            Some(PidEvent::Exec(pid))
        }
        binding::PROC_EVENT_EXIT => {
            let pid = (*proc_ev).event_data.exit.process_pid;
            Some(PidEvent::Exit(pid))
        }
        binding::PROC_EVENT_COREDUMP => {
            let pid = (*proc_ev).event_data.coredump.process_pid;
            Some(PidEvent::Coredump(pid))
        }
        _ => None,
    }
}

@ydirson
Copy link

ydirson commented Dec 24, 2024

I believe that in the function with the problem, you could possibly replace the *proc_ev with proc_ev.read_unaligned()?

We don't have direct control of proc_ev here, it is defined by

  1. the address of the buffer allocated in get_events, which is aligned aligned on 4-byte boundary since we allocate it as a Vec<u32>
  2. the offset of the data field, with cn_msg of size 20, which also makes id aligned on 4-bytes boundary but not 8.

The assertion is about being aligned to 8-bytes boundary, which makes it necessary for buffer to be specifically not aligned to 8-bytes boundary.

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

3 participants