Run rustfmt
This commit is contained in:
+84
-50
@@ -3,15 +3,20 @@
|
||||
use core::{
|
||||
convert::{TryFrom, TryInto},
|
||||
mem,
|
||||
num::ParseIntError,
|
||||
ops::{Deref, DerefMut},
|
||||
pin::Pin,
|
||||
primitive::str,
|
||||
ptr, slice, num::ParseIntError, str::Matches,
|
||||
ptr, slice,
|
||||
str::Matches,
|
||||
};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use alloc::{borrow::ToOwned, string::{String, FromUtf8Error}};
|
||||
use alloc::{
|
||||
borrow::ToOwned,
|
||||
string::{FromUtf8Error, String},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
@@ -19,9 +24,9 @@ use crate::{
|
||||
header::{errno, fcntl, string::strlen},
|
||||
io,
|
||||
io::{prelude::*, BufReader, Lines},
|
||||
platform::types::*,
|
||||
platform,
|
||||
sync::Mutex
|
||||
platform::types::*,
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
use super::{errno::*, string::strncmp};
|
||||
@@ -69,7 +74,9 @@ static mut GROUP: group = group {
|
||||
gr_mem: ptr::null_mut(),
|
||||
};
|
||||
|
||||
lazy_static! { static ref LINE_READER: Mutex<Option<Lines<BufReader<File>>>> = Mutex::new(None); }
|
||||
lazy_static! {
|
||||
static ref LINE_READER: Mutex<Option<Lines<BufReader<File>>>> = Mutex::new(None);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
@@ -88,7 +95,7 @@ enum Error {
|
||||
Misc(io::Error),
|
||||
FromUtf8Error(FromUtf8Error),
|
||||
ParseIntError(ParseIntError),
|
||||
Other
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -110,18 +117,17 @@ impl OwnedGrp {
|
||||
fn split(buf: &mut [u8]) -> Option<group> {
|
||||
let gid = match buf[0..mem::size_of::<gid_t>()].try_into() {
|
||||
Ok(buf) => gid_t::from_ne_bytes(buf),
|
||||
Err(err) => return None
|
||||
Err(err) => return None,
|
||||
};
|
||||
|
||||
|
||||
// We moved the gid to the beginning of the byte buffer so we can do this.
|
||||
let mut parts = buf[mem::size_of::<gid_t>()..].split_mut(|&c| c == b'\0');
|
||||
|
||||
|
||||
Some(group {
|
||||
gr_name: parts.next()?.as_mut_ptr() as *mut i8,
|
||||
gr_passwd: parts.next()?.as_mut_ptr() as *mut i8,
|
||||
gr_gid: gid,
|
||||
gr_mem: parts.next()?.as_mut_ptr() as *mut *mut c_char
|
||||
// this will work because this points to the first string, which also happens to be the start of the array. The two are equivalent, just need to by typecast.
|
||||
gr_mem: parts.next()?.as_mut_ptr() as *mut *mut c_char, // this will work because this points to the first string, which also happens to be the start of the array. The two are equivalent, just need to by typecast.
|
||||
})
|
||||
}
|
||||
|
||||
@@ -133,61 +139,61 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro
|
||||
.map(|i| if i == b':' { b'\0' } else { i })
|
||||
.chain([b'\0'])
|
||||
.collect::<Vec<_>>();
|
||||
let mut buffer = buffer
|
||||
.split_mut(|i| *i == b'\0');
|
||||
let mut buffer = buffer.split_mut(|i| *i == b'\0');
|
||||
|
||||
let mut gr_gid: gid_t = 0;
|
||||
let strings = {
|
||||
let mut vec: Vec<u8> = Vec::new();
|
||||
|
||||
|
||||
let gr_name = buffer.next().ok_or(Error::EOF)?.to_vec();
|
||||
let gr_passwd = buffer.next().ok_or(Error::EOF)?.to_vec();
|
||||
gr_gid = String::from_utf8(buffer.next().ok_or(Error::EOF)?.to_vec())
|
||||
.map_err(|err| Error::FromUtf8Error(err))?
|
||||
.parse::<gid_t>()
|
||||
.map_err(|err| Error::ParseIntError(err))?;
|
||||
|
||||
|
||||
// Place the gid at the beginning of the byte buffer to make getting it back out again later, much faster.
|
||||
|
||||
|
||||
vec.extend(gr_gid.to_ne_bytes());
|
||||
vec.extend(gr_name);
|
||||
vec.push(0);
|
||||
vec.extend(gr_passwd);
|
||||
vec.push(0);
|
||||
|
||||
for i in buffer.next().ok_or(Error::EOF)?
|
||||
|
||||
for i in buffer
|
||||
.next()
|
||||
.ok_or(Error::EOF)?
|
||||
.split(|b| *b == b',')
|
||||
.filter(|i| i.len() > 0) {
|
||||
|
||||
.filter(|i| i.len() > 0)
|
||||
{
|
||||
vec.extend(i.to_vec());
|
||||
vec.push(0);
|
||||
}
|
||||
|
||||
|
||||
vec.extend(0usize.to_ne_bytes());
|
||||
|
||||
|
||||
vec
|
||||
};
|
||||
|
||||
|
||||
let mut buffer = match destbuf {
|
||||
None => MaybeAllocated::Owned(Box::into_pin(strings.into_boxed_slice())),
|
||||
Some(buf) => {
|
||||
let mut buf = MaybeAllocated::Borrowed(buf);
|
||||
|
||||
|
||||
if buf.len() < buf.len() {
|
||||
unsafe { platform::errno = errno::ERANGE; }
|
||||
unsafe {
|
||||
platform::errno = errno::ERANGE;
|
||||
}
|
||||
return Err(Error::BufTooSmall);
|
||||
}
|
||||
|
||||
|
||||
buf[..strings.len()].copy_from_slice(&strings);
|
||||
buf
|
||||
}
|
||||
};
|
||||
let reference = split(&mut buffer).ok_or(Error::Other)?;
|
||||
|
||||
Ok(OwnedGrp {
|
||||
buffer,
|
||||
reference
|
||||
})
|
||||
|
||||
Ok(OwnedGrp { buffer, reference })
|
||||
}
|
||||
|
||||
// MT-Unsafe race:grgid locale
|
||||
@@ -198,7 +204,7 @@ pub unsafe extern "C" fn getgrgid(gid: gid_t) -> *mut group {
|
||||
for line in BufReader::new(db).lines() {
|
||||
let Ok(line) = line else { return ptr::null_mut() };
|
||||
let Ok(grp) = parse_grp(line, None) else { return ptr::null_mut() };
|
||||
|
||||
|
||||
if grp.reference.gr_gid == gid {
|
||||
return grp.into_global();
|
||||
}
|
||||
@@ -214,11 +220,16 @@ pub unsafe extern "C" fn getgrnam(name: *const c_char) -> *mut group {
|
||||
|
||||
for line in BufReader::new(db).lines() {
|
||||
let Ok(line) = line else { return ptr::null_mut() };
|
||||
|
||||
|
||||
let Ok(grp) = parse_grp(line, None) else { return ptr::null_mut() };
|
||||
|
||||
|
||||
// Attempt to prevent BO vulnerabilities
|
||||
if strncmp(grp.reference.gr_name, name, strlen(grp.reference.gr_name).min(strlen(name))) > 0 {
|
||||
if strncmp(
|
||||
grp.reference.gr_name,
|
||||
name,
|
||||
strlen(grp.reference.gr_name).min(strlen(name)),
|
||||
) > 0
|
||||
{
|
||||
return grp.into_global();
|
||||
}
|
||||
}
|
||||
@@ -228,7 +239,13 @@ pub unsafe extern "C" fn getgrnam(name: *const c_char) -> *mut group {
|
||||
|
||||
// MT-Safe locale
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getgrgid_r(gid: gid_t, result_buf: *mut group, buffer: *mut c_char, buflen: usize, result: *mut *mut group) -> c_int {
|
||||
pub unsafe extern "C" fn getgrgid_r(
|
||||
gid: gid_t,
|
||||
result_buf: *mut group,
|
||||
buffer: *mut c_char,
|
||||
buflen: usize,
|
||||
result: *mut *mut group,
|
||||
) -> c_int {
|
||||
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else { return ENOENT };
|
||||
|
||||
for line in BufReader::new(db).lines() {
|
||||
@@ -238,31 +255,42 @@ pub unsafe extern "C" fn getgrgid_r(gid: gid_t, result_buf: *mut group, buffer:
|
||||
if grp.reference.gr_gid == gid {
|
||||
*result_buf = grp.reference;
|
||||
*result = result_buf;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
// MT-Safe locale
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getgrnam_r(name: *const c_char, result_buf: *mut group, buffer: *mut c_char, buflen: usize, result: *mut *mut group) -> c_int {
|
||||
pub unsafe extern "C" fn getgrnam_r(
|
||||
name: *const c_char,
|
||||
result_buf: *mut group,
|
||||
buffer: *mut c_char,
|
||||
buflen: usize,
|
||||
result: *mut *mut group,
|
||||
) -> c_int {
|
||||
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else { return ENOENT };
|
||||
|
||||
for line in BufReader::new(db).lines() {
|
||||
let Ok(line) = line else { return EINVAL };
|
||||
let Ok(mut grp) = parse_grp(line, Some(DestBuffer { ptr: buffer as *mut u8, len: buflen })) else { return EINVAL };
|
||||
|
||||
if strncmp(grp.reference.gr_name, name, strlen(grp.reference.gr_name).min(strlen(name))) > 0 {
|
||||
if strncmp(
|
||||
grp.reference.gr_name,
|
||||
name,
|
||||
strlen(grp.reference.gr_name).min(strlen(name)),
|
||||
) > 0
|
||||
{
|
||||
*result_buf = grp.reference;
|
||||
*result = result_buf;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
@@ -270,20 +298,21 @@ pub unsafe extern "C" fn getgrnam_r(name: *const c_char, result_buf: *mut group,
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getgrent() -> *mut group {
|
||||
let mut line_reader = LINE_READER.lock();
|
||||
|
||||
|
||||
if line_reader.is_none() {
|
||||
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else { return ptr::null_mut() };
|
||||
*line_reader = Some(BufReader::new(db).lines());
|
||||
}
|
||||
|
||||
if let Some(lines) = line_reader.deref_mut() {
|
||||
|
||||
if let Some(lines) = line_reader.deref_mut() {
|
||||
let Some(line) = lines.next() else { return ptr::null_mut() };
|
||||
let Ok(line) = line else { return ptr::null_mut() };
|
||||
|
||||
|
||||
if let Ok(grp) = parse_grp(line, None) {
|
||||
return grp.into_global();
|
||||
} else { return ptr::null_mut(); }
|
||||
|
||||
} else {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
} else {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
@@ -299,13 +328,18 @@ pub unsafe extern "C" fn endgrent() {
|
||||
// MT-Unsafe race:grent locale
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn setgrent() {
|
||||
let mut line_reader = LINE_READER.lock();
|
||||
let mut line_reader = LINE_READER.lock();
|
||||
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else { return };
|
||||
*line_reader = Some(BufReader::new(db).lines());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getgrouplist(user: *const c_char, group: gid_t, groups: *mut gid_t, ngroups: i32) -> i32 {
|
||||
pub unsafe extern "C" fn getgrouplist(
|
||||
user: *const c_char,
|
||||
group: gid_t,
|
||||
groups: *mut gid_t,
|
||||
ngroups: i32,
|
||||
) -> i32 {
|
||||
let mut grps = Vec::<gid_t>::from_raw_parts(groups, 0, ngroups as usize);
|
||||
let Ok(usr) = (crate::c_str::CStr::from_ptr(user).to_str()) else { return 0 };
|
||||
|
||||
|
||||
+30
-23
@@ -4,8 +4,13 @@ use core::{char, ffi::VaList as va_list, mem, ptr, slice, usize};
|
||||
|
||||
use crate::{
|
||||
header::{
|
||||
ctype::isspace, errno::{ERANGE, EILSEQ, ENOMEM}, stdio::*,
|
||||
stdlib::{MB_CUR_MAX, MB_LEN_MAX, malloc}, string, time::*, wctype::*,
|
||||
ctype::isspace,
|
||||
errno::{EILSEQ, ENOMEM, ERANGE},
|
||||
stdio::*,
|
||||
stdlib::{malloc, MB_CUR_MAX, MB_LEN_MAX},
|
||||
string,
|
||||
time::*,
|
||||
wctype::*,
|
||||
},
|
||||
platform::{self, errno, types::*},
|
||||
};
|
||||
@@ -46,8 +51,13 @@ pub unsafe extern "C" fn fgetwc(stream: *mut FILE) -> wint_t {
|
||||
let mut wc: wchar_t = 0;
|
||||
|
||||
loop {
|
||||
let nread = fread(buf[bytes_read..bytes_read+1].as_mut_ptr() as *mut c_void, 1, 1, stream);
|
||||
|
||||
let nread = fread(
|
||||
buf[bytes_read..bytes_read + 1].as_mut_ptr() as *mut c_void,
|
||||
1,
|
||||
1,
|
||||
stream,
|
||||
);
|
||||
|
||||
if nread != 1 {
|
||||
errno = EILSEQ;
|
||||
return WEOF;
|
||||
@@ -75,7 +85,12 @@ pub unsafe extern "C" fn fgetwc(stream: *mut FILE) -> wint_t {
|
||||
}
|
||||
}
|
||||
|
||||
mbrtowc(&mut wc, buf.as_ptr() as *const c_char, encoded_length, ptr::null_mut());
|
||||
mbrtowc(
|
||||
&mut wc,
|
||||
buf.as_ptr() as *const c_char,
|
||||
encoded_length,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
|
||||
wc as wint_t
|
||||
}
|
||||
@@ -281,8 +296,8 @@ pub unsafe extern "C" fn ungetwc(wc: wint_t, stream: &mut FILE) -> wint_t {
|
||||
return WEOF;
|
||||
}
|
||||
|
||||
/*
|
||||
We might have unget multiple bytes for a single wchar, eg, `ç` is [195, 167].
|
||||
/*
|
||||
We might have unget multiple bytes for a single wchar, eg, `ç` is [195, 167].
|
||||
We need to unget them in reversed, so they are pused as [..., 167, 195, ...]
|
||||
When we do fgetwc, we pop from the Vec, getting the write order of bytes [195, 167].
|
||||
If we called ungetc in the non-reversed order, we would get [167, 195]
|
||||
@@ -327,19 +342,12 @@ pub unsafe extern "C" fn vswprintf(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wcpcpy(
|
||||
d: *mut wchar_t,
|
||||
s: *const wchar_t,
|
||||
) -> *mut wchar_t {
|
||||
pub unsafe extern "C" fn wcpcpy(d: *mut wchar_t, s: *const wchar_t) -> *mut wchar_t {
|
||||
return (wcscpy(d, s)).offset(wcslen(s) as isize);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wcpncpy(
|
||||
d: *mut wchar_t,
|
||||
s: *const wchar_t,
|
||||
n: size_t,
|
||||
) -> *mut wchar_t {
|
||||
pub unsafe extern "C" fn wcpncpy(d: *mut wchar_t, s: *const wchar_t, n: size_t) -> *mut wchar_t {
|
||||
return (wcsncpy(d, s, n)).offset(wcsnlen(s, n) as isize);
|
||||
}
|
||||
|
||||
@@ -359,8 +367,8 @@ pub unsafe extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wcsdup(s: *const wchar_t) -> *mut wchar_t {
|
||||
let l = wcslen(s);
|
||||
|
||||
let d = malloc((l + 1)*mem::size_of::<wchar_t>()) as *mut wchar_t;
|
||||
|
||||
let d = malloc((l + 1) * mem::size_of::<wchar_t>()) as *mut wchar_t;
|
||||
|
||||
if d.is_null() {
|
||||
errno = ENOMEM;
|
||||
@@ -521,7 +529,7 @@ pub unsafe extern "C" fn wcsncpy(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wcsnlen(mut s: *const wchar_t, maxlen: size_t) -> size_t {
|
||||
let mut len = 0;
|
||||
|
||||
|
||||
while len < maxlen {
|
||||
if *s == 0 {
|
||||
break;
|
||||
@@ -550,10 +558,10 @@ pub unsafe extern "C" fn wcsnrtombs(
|
||||
if ps.is_null() {
|
||||
ps = &mut mbs;
|
||||
}
|
||||
|
||||
|
||||
while read < nwc {
|
||||
buf.fill(0);
|
||||
|
||||
|
||||
let ret = wcrtomb(buf.as_mut_ptr(), **src, ps);
|
||||
|
||||
if ret == size_t::MAX {
|
||||
@@ -574,7 +582,7 @@ pub unsafe extern "C" fn wcsnrtombs(
|
||||
*src = ptr::null();
|
||||
return written;
|
||||
}
|
||||
|
||||
|
||||
*src = (*src).add(1);
|
||||
read += 1;
|
||||
written += ret;
|
||||
@@ -582,7 +590,6 @@ pub unsafe extern "C" fn wcsnrtombs(
|
||||
written
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wcspbrk(mut wcs: *const wchar_t, set: *const wchar_t) -> *mut wchar_t {
|
||||
wcs = wcs.add(wcscspn(wcs, set));
|
||||
|
||||
Reference in New Issue
Block a user