Skip to content

Unsoundness in Utsname::name and other function #120

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

Open
lwz23 opened this issue Dec 2, 2024 · 2 comments
Open

Unsoundness in Utsname::name and other function #120

lwz23 opened this issue Dec 2, 2024 · 2 comments

Comments

@lwz23
Copy link

lwz23 commented Dec 2, 2024

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.
@lwz23
Copy link
Author

lwz23 commented Dec 2, 2024

same problem for nodename,release,version and machine

pub fn nodename(&self) -> &str {

pub fn release(&self) -> &str {

pub fn version(&self) -> &str {

pub fn machine(&self) -> &str {

@lwz23 lwz23 changed the title Unsoundness in Utsname::name Unsoundness in Utsname::name and other function Dec 2, 2024
@lwz23
Copy link
Author

lwz23 commented Dec 4, 2024

ping?

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

1 participant