From d6ee13ed9e818aa51b8d86d95e8009a376289a40 Mon Sep 17 00:00:00 2001 From: Jeron Aldaron Lau Date: Sun, 3 Mar 2024 00:19:23 -0600 Subject: [PATCH] Fix Instances of Memory Corruption on Illumos (#93) --- TESTING.md | 66 ++++++++++++++++++++++++++++++++++++++ src/os/unix.rs | 87 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 138 insertions(+), 15 deletions(-) diff --git a/TESTING.md b/TESTING.md index 7dc6b61..172359e 100644 --- a/TESTING.md +++ b/TESTING.md @@ -2,6 +2,72 @@ This file outlines the regression testing plan for all platforms. +## Linux / Fedora Silverblue + +## Linux / Ubuntu + +## Windows + +## MacOS + +## FreeBSD + +## Illumos + +Testing is done on Tribblix (virtualized on Fedora Silverblue): + + + +Download the 64-bit x86/x64 standard image. + +Install it in GNOME Boxes (select operating system OpenIndiana Hipster). + +Set 4 GiB memory, and 16 GiB Storage limit + +Login as `jack` (password `jack`) + +```shell +su - root # password `tribblix` +format # 0, quit +./live_install -G c1t0d0 develop # replace c1t0d0 with disk +reboot -p +``` + +Login as `jack` (password `jack`) + +Now, install Rust (use bash instead of sh, sh doesn't work) + +```shell +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash # 1 +source "$HOME/.cargo/env" +``` + +### Testing + +```shell +git clone https://github.com/ardaku/whoami.git +cd whoami +# run both debug and release +cargo run --example whoami-demo +cargo run --example whoami-demo --release +``` + +Expected output is + +```console +WhoAmI 1.5.0-pre.0 + +User's Language whoami::langs(): +User's Name whoami::realname(): Tribblix Jack +User's Username whoami::username(): jack +Device's Pretty Name whoami::devicename(): tribblix +Device's Hostname whoami::fallible::hostname(): tribblix +Device's Platform whoami::platform(): Illumos +Device's OS Distro whoami::distro(): Tribblix +Device's Desktop Env. whoami::desktop_env(): Unknown: Unknown +Device's CPU Arch whoami::arch(): Unknown: i86pc +``` + ## Redox diff --git a/src/os/unix.rs b/src/os/unix.rs index bde8d7b..2f88676 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -29,7 +29,8 @@ use crate::{ target_os = "dragonfly", target_os = "bitrig", target_os = "openbsd", - target_os = "netbsd" + target_os = "netbsd", + target_os = "illumos", )))] #[repr(C)] struct PassWd { @@ -65,6 +66,31 @@ struct PassWd { pw_fields: i32, } +#[cfg(target_os = "illumos")] +#[repr(C)] +struct PassWd { + pw_name: *const c_void, + pw_passwd: *const c_void, + pw_uid: u32, + pw_gid: u32, + pw_age: *const c_void, + pw_comment: *const c_void, + pw_gecos: *const c_void, + pw_dir: *const c_void, + pw_shell: *const c_void, +} + +#[cfg(target_os = "illumos")] +extern "system" { + fn getpwuid_r( + uid: u32, + pwd: *mut PassWd, + buf: *mut c_void, + buflen: c_int, + ) -> *mut PassWd; +} + +#[cfg(not(target_os = "illumos"))] extern "system" { fn getpwuid_r( uid: u32, @@ -73,6 +99,9 @@ extern "system" { buflen: usize, result: *mut *mut PassWd, ) -> i32; +} + +extern "system" { fn geteuid() -> u32; fn gethostname(name: *mut c_void, len: usize) -> i32; } @@ -204,22 +233,41 @@ fn getpwuid(name: Name) -> Result { // Get PassWd `struct`. let passwd = unsafe { - let ret = getpwuid_r( - geteuid(), - passwd.as_mut_ptr(), - buffer.as_mut_ptr() as *mut c_void, - BUF_SIZE, - _passwd.as_mut_ptr(), - ); - - if ret != 0 { - return Err(Error::last_os_error()); + #[cfg(not(target_os = "illumos"))] + { + let ret = getpwuid_r( + geteuid(), + passwd.as_mut_ptr(), + buffer.as_mut_ptr() as *mut c_void, + BUF_SIZE, + _passwd.as_mut_ptr(), + ); + + if ret != 0 { + return Err(Error::last_os_error()); + } + + let _passwd = _passwd.assume_init(); + + if _passwd.is_null() { + return Err(super::err_null_record()); + } } - let _passwd = _passwd.assume_init(); + #[cfg(target_os = "illumos")] + { + use std::convert::TryInto; + + let ret = getpwuid_r( + geteuid(), + passwd.as_mut_ptr(), + buffer.as_mut_ptr() as *mut c_void, + BUF_SIZE.try_into().unwrap_or(c_int::MAX), + ); - if _passwd.is_null() { - return Err(super::err_null_record()); + if ret.is_null() { + return Err(Error::last_os_error()); + } } passwd.assume_init() @@ -344,7 +392,6 @@ pub(crate) fn lang() -> impl Iterator { target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "illumos" ))] #[repr(C)] struct UtsName { @@ -355,6 +402,16 @@ struct UtsName { machine: [c_char; 256], } +#[cfg(target_os = "illumos")] +#[repr(C)] +struct UtsName { + sysname: [c_char; 257], + nodename: [c_char; 257], + release: [c_char; 257], + version: [c_char; 257], + machine: [c_char; 257], +} + #[cfg(target_os = "dragonfly")] #[repr(C)] struct UtsName {