Add check during the conversion from timeval_t to Duration

This commit is contained in:
Marsman1996 2024-09-19 10:20:03 +08:00 committed by Tate, Hongliang Tian
parent 70505ff4f8
commit 4fa4e5ef2a
3 changed files with 23 additions and 7 deletions

View File

@ -19,8 +19,10 @@ pub fn sys_select(
let timeout = if timeval_addr == 0 {
None
} else {
let timeval = ctx.get_user_space().read_val::<timeval_t>(timeval_addr)?;
Some(Duration::from(timeval))
let mut timeval = ctx.get_user_space().read_val::<timeval_t>(timeval_addr)?;
timeval.sec += timeval.usec / 1_000_000;
timeval.usec %= 1_000_000;
Some(Duration::try_from(timeval)?)
};
do_sys_select(

View File

@ -34,8 +34,8 @@ pub fn sys_setitimer(
}
let user_space = ctx.get_user_space();
let new_itimerval = user_space.read_val::<itimerval_t>(new_itimerval_addr)?;
let interval = Duration::from(new_itimerval.it_interval);
let expire_time = Duration::from(new_itimerval.it_value);
let interval = Duration::try_from(new_itimerval.it_interval)?;
let expire_time = Duration::try_from(new_itimerval.it_value)?;
let process_timer_manager = ctx.process.timer_manager();
let timer = match ItimerType::try_from(itimer_type)? {

View File

@ -86,9 +86,23 @@ impl From<Duration> for timeval_t {
}
}
impl From<timeval_t> for Duration {
fn from(timeval: timeval_t) -> Self {
Duration::new(timeval.sec as u64, (timeval.usec * 1000) as u32)
impl TryFrom<timeval_t> for Duration {
type Error = crate::Error;
fn try_from(timeval: timeval_t) -> Result<Self> {
if timeval.sec < 0 || timeval.usec < 0 {
return_errno_with_message!(Errno::EINVAL, "timeval_t cannot be negative");
}
if timeval.usec > 1_000_000 {
// The value of microsecond cannot exceed 10^6,
// otherwise the value for seconds should be set.
return_errno_with_message!(Errno::EINVAL, "nsec is not normalized");
}
Ok(Duration::new(
timeval.sec as u64,
(timeval.usec * 1000) as u32,
))
}
}