Skip to content

Unsoundness in Utsname::name and other function #120

Open
@lwz23

Description

@lwz23

Description
I notice the following code.

unsafe { core::str::from_utf8_unchecked(&self.sysname) }

pub struct Utsname {
    pub sysname: [u8; 65],
    pub nodename: [u8; 65],
    pub release: [u8; 65],
    pub version: [u8; 65],
    pub machine: [u8; 65],
    pub domainname: [u8; 65],
}

impl Utsname {
    pub fn name(&self) -> &str {
        unsafe { core::str::from_utf8_unchecked(&self.sysname) }
    }
.....................
}

I think there may be an unsound problem here because Utsname is a pub struct, and sysname is also declared as a pub field, which means that the user may manipulate the sysname field directly. This sysname field is then passed directly into the unsafe API from_utf8_unchecked, which leads to potential UB problems.

PoC:

pub struct Utsname {
    pub sysname: [u8; 65],
    pub nodename: [u8; 65],
    pub release: [u8; 65],
    pub version: [u8; 65],
    pub machine: [u8; 65],
    pub domainname: [u8; 65],
}

impl Utsname {
    pub fn name(&self) -> &str {
        unsafe { core::str::from_utf8_unchecked(&self.sysname) }
    }
}

fn main() {
    let utsname = Utsname {
        sysname: [0xFF; 65], // Invalid UTF-8
        nodename: [0; 65],
        release: [0; 65],
        version: [0; 65],
        machine: [0; 65],
        domainname: [0; 65],
    };

    // Trigger UB: Access as valid UTF-8 slice
    let invalid_utf8 = utsname.name();

    // Force an operation on the invalid UTF-8 slice
    for _ in invalid_utf8.chars() {
        // This would cause UB if the input is not valid UTF-8
    }
}

Result:

PS E:\Github\lwz> cargo run
   Compiling lwz v0.1.0 (E:\Github\lwz)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.24s
     Running `target\debug\lwz.exe`
thread 'main' panicked at core\src\panicking.rs:223:5:
unsafe precondition(s) violated: invalid value for `char`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
error: process didn't exit successfully: `target\debug\lwz.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN)

Suggestion

  1. use from_utf8 to replace from_utf8_unchecked.
  2. declear sysname as private.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions