Fixed utimes segfault when given nullptr

This commit is contained in:
Martin Welgemoed
2023-12-07 15:39:38 +00:00
committed by Jeremy Soller
parent 84de1e8234
commit 02780057f0
2 changed files with 39 additions and 16 deletions
+20 -11
View File
@@ -5,6 +5,7 @@ use crate::{
header::time::timespec,
platform::{types::*, Pal, PalSignal, Sys},
};
use core::ptr::null;
pub const ITIMER_REAL: c_int = 0;
pub const ITIMER_VIRTUAL: c_int = 1;
@@ -57,15 +58,23 @@ pub extern "C" fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
#[no_mangle]
pub unsafe extern "C" fn utimes(path: *const c_char, times: *const timeval) -> c_int {
let path = CStr::from_ptr(path);
let times_spec = [
timespec {
tv_sec: (*times.offset(0)).tv_sec,
tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000,
},
timespec {
tv_sec: (*times.offset(1)).tv_sec,
tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000,
},
];
Sys::utimens(path, times_spec.as_ptr())
// Nullptr is valid here, it means "use current time"
let times_spec = if times.is_null() {
null()
} else {
{
[
timespec {
tv_sec: (*times.offset(0)).tv_sec,
tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000,
},
timespec {
tv_sec: (*times.offset(1)).tv_sec,
tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000,
},
]
}
.as_ptr()
};
Sys::utimens(path, times_spec)
}
+19 -5
View File
@@ -3,7 +3,7 @@ use core::{slice, str};
use syscall::{Error, Result, WaitFlags, EMFILE};
use crate::{
header::{signal::sigaction, time::timespec},
header::{signal::sigaction, sys_stat::UTIME_NOW, time::timespec},
platform::types::*,
};
@@ -77,10 +77,24 @@ pub unsafe fn fstatvfs(
Ok(())
}
pub unsafe fn futimens(fd: usize, times: *const timespec) -> syscall::Result<()> {
let times = times
.cast::<[timespec; 2]>()
.read()
.map(|ts| syscall::TimeSpec::from(&ts));
let times = if times.is_null() {
// null means set to current time using special UTIME_NOW value (tv_sec is ignored in that case)
[
syscall::TimeSpec {
tv_sec: 0,
tv_nsec: UTIME_NOW as c_int,
},
syscall::TimeSpec {
tv_sec: 0,
tv_nsec: UTIME_NOW as c_int,
},
]
} else {
times
.cast::<[timespec; 2]>()
.read()
.map(|ts| syscall::TimeSpec::from(&ts))
};
syscall::futimens(fd as usize, &times)?;
Ok(())
}