From 68501278ab78bd1f888b2488263fd70a52c63ee8 Mon Sep 17 00:00:00 2001 From: sunhaosheng Date: Wed, 17 Dec 2025 14:29:28 +0800 Subject: [PATCH 1/6] fix(task): read child pid/exit_code before free in waitpid In sys_waitpid, child.pid() and child.exit_code() were read after calling child.free(), which could lead to use-after-free issues. Fix: Read pid and exit_code before calling free(). --- api/src/syscall/task/wait.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/syscall/task/wait.rs b/api/src/syscall/task/wait.rs index 589c17bf..d650b32e 100644 --- a/api/src/syscall/task/wait.rs +++ b/api/src/syscall/task/wait.rs @@ -90,13 +90,15 @@ pub fn sys_waitpid(pid: i32, exit_code: *mut i32, options: u32) -> AxResult Date: Wed, 17 Dec 2025 14:29:37 +0800 Subject: [PATCH 2/6] fix(task): fix PR_SET_MM handling in prctl PR_SET_MM_* constants were incorrectly matched at the top level of prctl instead of as sub-options of PR_SET_MM. Fix: Restructure the match to handle PR_SET_MM with its sub-options properly, and add more PR_SET_MM sub-options (BRK, ARG_*, ENV_*, etc.) --- api/src/syscall/task/ctl.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/api/src/syscall/task/ctl.rs b/api/src/syscall/task/ctl.rs index 97a99eff..a039eba2 100644 --- a/api/src/syscall/task/ctl.rs +++ b/api/src/syscall/task/ctl.rs @@ -99,12 +99,26 @@ pub fn sys_prctl( } PR_SET_SECCOMP => {} PR_MCE_KILL => {} - PR_SET_MM_START_CODE - | PR_SET_MM_END_CODE - | PR_SET_MM_START_DATA - | PR_SET_MM_END_DATA - | PR_SET_MM_START_BRK - | PR_SET_MM_START_STACK => {} + PR_SET_MM => match arg2 as u32 { + PR_SET_MM_START_CODE + | PR_SET_MM_END_CODE + | PR_SET_MM_START_DATA + | PR_SET_MM_END_DATA + | PR_SET_MM_START_BRK + | PR_SET_MM_BRK + | PR_SET_MM_START_STACK + | PR_SET_MM_ARG_START + | PR_SET_MM_ARG_END + | PR_SET_MM_ENV_START + | PR_SET_MM_ENV_END + | PR_SET_MM_AUXV + | PR_SET_MM_EXE_FILE + | PR_SET_MM_MAP => {} + _ => { + warn!("sys_prctl: unsupported PR_SET_MM sub-option {:#x}", arg2); + return Err(AxError::InvalidInput); + } + }, _ => { warn!("sys_prctl: unsupported option {option}"); return Err(AxError::InvalidInput); From c915497e9de97c086ff33c706fe3e781a7911ea0 Mon Sep 17 00:00:00 2001 From: sunhaosheng Date: Wed, 17 Dec 2025 14:29:44 +0800 Subject: [PATCH 3/6] feat(syscall): add mincore syscall stub Add sys_mincore that returns ENOSYS (Unsupported). This is safer than returning incorrect data and lets programs use fallback logic. --- api/src/syscall/mm/mmap.rs | 6 ++++++ api/src/syscall/mod.rs | 1 + 2 files changed, 7 insertions(+) diff --git a/api/src/syscall/mm/mmap.rs b/api/src/syscall/mm/mmap.rs index 94793882..0224b76a 100644 --- a/api/src/syscall/mm/mmap.rs +++ b/api/src/syscall/mm/mmap.rs @@ -335,3 +335,9 @@ pub fn sys_mlock(addr: usize, length: usize) -> AxResult { pub fn sys_mlock2(_addr: usize, _length: usize, _flags: u32) -> AxResult { Ok(0) } + +/// Check whether pages are resident in memory. +/// Returns ENOSYS (Unsupported) to let programs use fallback logic. +pub fn sys_mincore(_addr: usize, _length: usize, _vec: usize) -> AxResult { + Err(AxError::Unsupported) +} diff --git a/api/src/syscall/mod.rs b/api/src/syscall/mod.rs index aea95737..df60adde 100644 --- a/api/src/syscall/mod.rs +++ b/api/src/syscall/mod.rs @@ -357,6 +357,7 @@ pub fn handle_syscall(uctx: &mut UserContext) { Sysno::msync => sys_msync(uctx.arg0(), uctx.arg1() as _, uctx.arg2() as _), Sysno::mlock => sys_mlock(uctx.arg0(), uctx.arg1() as _), Sysno::mlock2 => sys_mlock2(uctx.arg0(), uctx.arg1() as _, uctx.arg2() as _), + Sysno::mincore => sys_mincore(uctx.arg0(), uctx.arg1() as _, uctx.arg2()), // task info Sysno::getpid => sys_getpid(), From f05b84a7b9fc19a4c994ec80bc104e410f052b75 Mon Sep 17 00:00:00 2001 From: sunhaosheng Date: Thu, 18 Dec 2025 16:51:09 +0800 Subject: [PATCH 4/6] fix fmt --- api/src/syscall/fs/io.rs | 16 ++++++++-------- api/src/syscall/io_mpx/select.rs | 30 +++++++++++++++--------------- api/src/syscall/resources.rs | 11 +++++------ 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/api/src/syscall/fs/io.rs b/api/src/syscall/fs/io.rs index 58d4f2bd..64f59f38 100644 --- a/api/src/syscall/fs/io.rs +++ b/api/src/syscall/fs/io.rs @@ -408,10 +408,10 @@ pub fn sys_splice( } has_pipe = true; } - if let Ok(file) = File::from_fd(fd_in) - && file.inner().is_path() - { - return Err(AxError::InvalidInput); + if let Ok(file) = File::from_fd(fd_in) { + if file.inner().is_path() { + return Err(AxError::InvalidInput); + } } SendFile::Direct(get_file_like(fd_in)?) }; @@ -428,10 +428,10 @@ pub fn sys_splice( } has_pipe = true; } - if let Ok(file) = File::from_fd(fd_out) - && file.inner().access(FileFlags::APPEND).is_ok() - { - return Err(AxError::InvalidInput); + if let Ok(file) = File::from_fd(fd_out) { + if file.inner().access(FileFlags::APPEND).is_ok() { + return Err(AxError::InvalidInput); + } } let f = get_file_like(fd_out)?; f.write(&mut b"".as_slice().into())?; diff --git a/api/src/syscall/io_mpx/select.rs b/api/src/syscall/io_mpx/select.rs index 3ff65f99..46650da5 100644 --- a/api/src/syscall/io_mpx/select.rs +++ b/api/src/syscall/io_mpx/select.rs @@ -114,23 +114,23 @@ fn do_select( let mut res = 0usize; for ((fd, interested), index) in fds.0.iter().zip(fd_indices.iter().copied()) { let events = fd.poll() & *interested; - if events.contains(IoEvents::IN) - && let Some(set) = readfds.as_deref_mut() - { - res += 1; - unsafe { FD_SET(index as _, set) }; + if events.contains(IoEvents::IN) { + if let Some(set) = readfds.as_deref_mut() { + res += 1; + unsafe { FD_SET(index as _, set) }; + } } - if events.contains(IoEvents::OUT) - && let Some(set) = writefds.as_deref_mut() - { - res += 1; - unsafe { FD_SET(index as _, set) }; + if events.contains(IoEvents::OUT) { + if let Some(set) = writefds.as_deref_mut() { + res += 1; + unsafe { FD_SET(index as _, set) }; + } } - if events.contains(IoEvents::ERR) - && let Some(set) = exceptfds.as_deref_mut() - { - res += 1; - unsafe { FD_SET(index as _, set) }; + if events.contains(IoEvents::ERR) { + if let Some(set) = exceptfds.as_deref_mut() { + res += 1; + unsafe { FD_SET(index as _, set) }; + } } } if res > 0 { diff --git a/api/src/syscall/resources.rs b/api/src/syscall/resources.rs index 8bf4ce35..13dd9d62 100644 --- a/api/src/syscall/resources.rs +++ b/api/src/syscall/resources.rs @@ -106,13 +106,12 @@ pub fn sys_getrusage(who: i32, usage: *mut rusage) -> AxResult { .threads() .into_iter() .fold(Rusage::default(), |acc, child| { - if let Ok(task) = get_task(child) - && !curr.ptr_eq(&task) - { - acc.collate(Rusage::from_thread(task.as_thread())) - } else { - acc + if let Ok(task) = get_task(child) { + if !curr.ptr_eq(&task) { + return acc.collate(Rusage::from_thread(task.as_thread())); + } } + acc }) } RUSAGE_THREAD => Rusage::from_thread(thr), From b1b5093bb9061f91f901d4f627c875296581f8b6 Mon Sep 17 00:00:00 2001 From: sunhaosheng Date: Thu, 18 Dec 2025 17:13:46 +0800 Subject: [PATCH 5/6] fix clippy --- api/src/syscall/fs/io.rs | 12 ++++++------ api/src/syscall/io_mpx/select.rs | 15 +++++++++------ api/src/syscall/resources.rs | 10 ++++------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/api/src/syscall/fs/io.rs b/api/src/syscall/fs/io.rs index 64f59f38..3c43730a 100644 --- a/api/src/syscall/fs/io.rs +++ b/api/src/syscall/fs/io.rs @@ -408,10 +408,9 @@ pub fn sys_splice( } has_pipe = true; } - if let Ok(file) = File::from_fd(fd_in) { - if file.inner().is_path() { - return Err(AxError::InvalidInput); - } + match File::from_fd(fd_in) { + Ok(file) if file.inner().is_path() => return Err(AxError::InvalidInput), + _ => {} } SendFile::Direct(get_file_like(fd_in)?) }; @@ -428,10 +427,11 @@ pub fn sys_splice( } has_pipe = true; } - if let Ok(file) = File::from_fd(fd_out) { - if file.inner().access(FileFlags::APPEND).is_ok() { + match File::from_fd(fd_out) { + Ok(file) if file.inner().access(FileFlags::APPEND).is_ok() => { return Err(AxError::InvalidInput); } + _ => {} } let f = get_file_like(fd_out)?; f.write(&mut b"".as_slice().into())?; diff --git a/api/src/syscall/io_mpx/select.rs b/api/src/syscall/io_mpx/select.rs index 46650da5..6153423e 100644 --- a/api/src/syscall/io_mpx/select.rs +++ b/api/src/syscall/io_mpx/select.rs @@ -114,23 +114,26 @@ fn do_select( let mut res = 0usize; for ((fd, interested), index) in fds.0.iter().zip(fd_indices.iter().copied()) { let events = fd.poll() & *interested; - if events.contains(IoEvents::IN) { - if let Some(set) = readfds.as_deref_mut() { + match (events.contains(IoEvents::IN), readfds.as_deref_mut()) { + (true, Some(set)) => { res += 1; unsafe { FD_SET(index as _, set) }; } + _ => {} } - if events.contains(IoEvents::OUT) { - if let Some(set) = writefds.as_deref_mut() { + match (events.contains(IoEvents::OUT), writefds.as_deref_mut()) { + (true, Some(set)) => { res += 1; unsafe { FD_SET(index as _, set) }; } + _ => {} } - if events.contains(IoEvents::ERR) { - if let Some(set) = exceptfds.as_deref_mut() { + match (events.contains(IoEvents::ERR), exceptfds.as_deref_mut()) { + (true, Some(set)) => { res += 1; unsafe { FD_SET(index as _, set) }; } + _ => {} } } if res > 0 { diff --git a/api/src/syscall/resources.rs b/api/src/syscall/resources.rs index 13dd9d62..3c0370e6 100644 --- a/api/src/syscall/resources.rs +++ b/api/src/syscall/resources.rs @@ -105,13 +105,11 @@ pub fn sys_getrusage(who: i32, usage: *mut rusage) -> AxResult { .proc .threads() .into_iter() - .fold(Rusage::default(), |acc, child| { - if let Ok(task) = get_task(child) { - if !curr.ptr_eq(&task) { - return acc.collate(Rusage::from_thread(task.as_thread())); - } + .fold(Rusage::default(), |acc, child| match get_task(child) { + Ok(task) if !curr.ptr_eq(&task) => { + acc.collate(Rusage::from_thread(task.as_thread())) } - acc + _ => acc, }) } RUSAGE_THREAD => Rusage::from_thread(thr), From d2592413830eaaee4e03fe623eb04bbda6e6da26 Mon Sep 17 00:00:00 2001 From: sunhaosheng Date: Thu, 18 Dec 2025 17:21:26 +0800 Subject: [PATCH 6/6] fix clippy2 --- api/src/syscall/io_mpx/select.rs | 33 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/api/src/syscall/io_mpx/select.rs b/api/src/syscall/io_mpx/select.rs index 6153423e..7d01287a 100644 --- a/api/src/syscall/io_mpx/select.rs +++ b/api/src/syscall/io_mpx/select.rs @@ -114,26 +114,23 @@ fn do_select( let mut res = 0usize; for ((fd, interested), index) in fds.0.iter().zip(fd_indices.iter().copied()) { let events = fd.poll() & *interested; - match (events.contains(IoEvents::IN), readfds.as_deref_mut()) { - (true, Some(set)) => { - res += 1; - unsafe { FD_SET(index as _, set) }; - } - _ => {} + if let (true, Some(set)) = + (events.contains(IoEvents::IN), readfds.as_deref_mut()) + { + res += 1; + unsafe { FD_SET(index as _, set) }; } - match (events.contains(IoEvents::OUT), writefds.as_deref_mut()) { - (true, Some(set)) => { - res += 1; - unsafe { FD_SET(index as _, set) }; - } - _ => {} + if let (true, Some(set)) = + (events.contains(IoEvents::OUT), writefds.as_deref_mut()) + { + res += 1; + unsafe { FD_SET(index as _, set) }; } - match (events.contains(IoEvents::ERR), exceptfds.as_deref_mut()) { - (true, Some(set)) => { - res += 1; - unsafe { FD_SET(index as _, set) }; - } - _ => {} + if let (true, Some(set)) = + (events.contains(IoEvents::ERR), exceptfds.as_deref_mut()) + { + res += 1; + unsafe { FD_SET(index as _, set) }; } } if res > 0 {