rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.23k stars 679 forks source link

bindgen fails with SIGSEGV: invalid memory reference #2762

Closed tmvkrpxl0 closed 3 months ago

tmvkrpxl0 commented 4 months ago

Input C/C++ Header

it's entirely composed of #include statements

Bindgen Invocation

let bindings = bindgen::Builder::default()
    .header("cpp/bindings.h")
    .clang_args([
        "-x", "c++",
        "-Icpp/public",
        "-Icpp/public/tier0",
        "-Icpp/public/tier1",
        "-Icpp/public/bitmap",
        "-Wno-inconsistent-missing-override",
        "-D", "GNUC=1",
        "-D", "POSIX=1",
        "-D", "_LINUX=1",
        "-D", "LINUX=1",
    ])
    .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
    .generate()
    .expect("Unable to generate bindings");

Actual Results

error: failed to run custom build command for `vgui-rs v0.1.0 (/home/tmvkrpxl0/CLionProjects/vgui-rs)`
note: To improve backtraces for build dependencies, set the CARGO_PROFILE_DEV_BUILD_OVERRIDE_DEBUG=true environment variable to enable debug information generation.

Caused by:
  process didn't exit successfully: `/home/tmvkrpxl0/CLionProjects/vgui-rs/target/debug/build/vgui-rs-4610f4fb4fd62aea/build-script-build` (signal: 11, SIGSEGV: invalid memory reference)
  --- stdout
  (and then bunch of file paths for my project)

I recently decided to experiment with Valve's vgui so I extracted portion of Source Engine 2013 Multiplayer branch from here: https://github.com/ValveSoftware/source-sdk-2013/tree/master Code I'm currently working with is here. I can mirror it to github if it's needed: https://codeberg.org/tmvkrpxl0/vgui-rs/src/branch/master/src I was following tutorial from official book of rust-bindgen, and I added few clang flag as it didn't compile. In my repo I also included cmake config as well to see if it even compiles at all, and it does.

boydjohnson commented 3 months ago

I was able to get the seg fault using a debug build of bindgen. I ran it under the debugger.

This is the head of the stacktrace

(gdb) where
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:872
#1  0x00007ffff6405cb1 in ?? () from /usr/lib/x86_64-linux-gnu/libclang-14.so.14.0.0
#2  0x00007ffff63a6fae in ?? () from /usr/lib/x86_64-linux-gnu/libclang-14.so.14.0.0
#3  0x0000555555c6e720 in clang_sys::clang_getFieldDeclBitWidth (cursor=...) at src/link.rs:153
#4  0x00005555559207f6 in bindgen::clang::Cursor::bit_width (self=0x7ffffffe53c8)
    at bindgen/clang.rs:710
#5  0x00005555559f4699 in bindgen::ir::comp::{impl#17}::from_ty::{closure#1} (cur=...)
    at bindgen/ir/comp.rs:1312
#6  0x00005555559ba9e8 in bindgen::clang::visit_children<bindgen::ir::comp::{impl#17}::from_ty::{closure_env#1}> (cur=..., _parent=..., data=0x7ffffffe5ab8) at bindgen/clang.rs:1127

Running it with the address sanitizer shows that it is a buffer overflow and there is a particularly large read operation.

==275259==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55e2556a4ce6 at pc 0x55e2529b38b1 bp 0x7ffd5f9cf2d0 sp 0x7ffd5f9cea88
READ of size 306568064 at 0x55e2556a4ce6 thread T0

I'm having problems dumping preprocessor input using clang due to some c headers included with the c++.

backtrace-v0.69.4.txt sanitizer.txt

boydjohnson commented 3 months ago

I was able to run creduce on it. This is what creduce resulted in.

template <int a> class b { int : a; };

which does segfault bindgen.

This looks like a templated bitfield class.

template<int a> class b { unsigned int: a; };

This template segfaults bindgen as well.

tmvkrpxl0 commented 3 months ago

thanks fir narrowing down the issue, I moved on from the project and forgot about it.

emilio commented 3 months ago

I can't repro that locally. Do you know what libclang version you're using? I suspect this is a clang bug.

emilio commented 3 months ago

Ah, this is a dupe of https://github.com/rust-lang/rust-bindgen/issues/2239, which was worked around, and there's an upstream issue which is fixed already.