gimli-rs / object

A unified interface for reading and writing object file formats
https://docs.rs/object/
Apache License 2.0
658 stars 149 forks source link

Unsafe code #664

Closed Cr0a3 closed 6 months ago

Cr0a3 commented 6 months ago

Hi, I currently make an experiment with your libary and the gimli libary to write a object file which has debugging symbols. But when i run my code, i get following error:

thread 'main' panicked at C:\Users\toni-\.cargo\registry\src\index.crates.io-6f17d22bba15001f\object-0.34.0\src\write\mod.rs:778:34:
attempt to subtract with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\debugobjtest.exe` (exit code: 101)

Which is in your crate the following lines: debug_assert_eq!(align & (align - 1), 0); <- Maybe point out that align cannot be 0?

My code looks like followed:

use std::fs::File;

use gimli::{write::{Address, DwarfUnit, EndianVec, Error, LineString, Sections}, Encoding};

use object::{
    write::Object, Architecture, BinaryFormat, Endianness
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut dwarf = DwarfUnit::new(Encoding {
        format: gimli::Format::Dwarf32,
        version: 5,
        address_size: 8,
    });

    let directory_id = dwarf.unit.line_program.add_directory(LineString::String(b"src/".into()));
    let file_id = dwarf.unit.line_program.add_file(LineString::String(b"test.c".into()), directory_id, None);

    let address = Some(Address::Constant(5));

    dwarf.unit.line_program.begin_sequence(address);
    dwarf.unit.line_program.row().file = file_id;
    dwarf.unit.line_program.row().line = 2;
    dwarf.unit.line_program.row().column = 1;
    dwarf.unit.line_program.row().address_offset = 0x0f;
    dwarf.unit.line_program.end_sequence(4);

    let mut obj = Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);

    let mut sections = Sections::new(EndianVec::new(gimli::LittleEndian));
    dwarf.write(&mut sections)?;
    sections.for_each(|id, data| {
        let data = data.clone().into_vec();
        let section = obj.add_section(vec![], id.name().as_bytes().into(), object::SectionKind::Debug);
        let sec = obj.section_mut(section);
        sec.append_data(&data, 0);

        Ok::<(), Error>(())
    })?;

    let file = File::create("test.o")?;
    obj.write_stream(file)?;

    Ok(())

}

When i change the align to 1 the issue is away.

Fix:

Point out that the align cannot be 0

Bye

philipc commented 6 months ago

Note that in Rust integer overflow is not the same as unsafe code.