starnix_modules_userfaultfd/
syscalls.rs1use starnix_core::security;
6use starnix_core::task::CurrentTask;
7use starnix_core::vfs::{FdFlags, FdNumber};
8use starnix_logging::track_stub;
9use starnix_sync::{Locked, Unlocked};
10use starnix_uapi::auth::CAP_SYS_PTRACE;
11use starnix_uapi::errors::Errno;
12use starnix_uapi::open_flags::OpenFlags;
13use starnix_uapi::{O_CLOEXEC, O_NONBLOCK, UFFD_USER_MODE_ONLY, error};
14
15use crate::userfault_file::UserFaultFile;
16
17pub fn sys_userfaultfd(
18 locked: &mut Locked<Unlocked>,
19 current_task: &CurrentTask,
20 raw_flags: u32,
21) -> Result<FdNumber, Errno> {
22 let unknown_flags = raw_flags & !(O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY);
23 if unknown_flags != 0 {
24 return error!(EINVAL, format!("unknown flags provided: {unknown_flags:x?}"));
25 }
26 let mut open_flags = OpenFlags::empty();
27 if raw_flags & O_NONBLOCK != 0 {
28 open_flags |= OpenFlags::NONBLOCK;
29 }
30 if raw_flags & O_CLOEXEC != 0 {
31 open_flags |= OpenFlags::CLOEXEC;
32 }
33
34 let fd_flags = if raw_flags & O_CLOEXEC != 0 {
35 FdFlags::CLOEXEC
36 } else {
37 track_stub!(TODO("https://fxbug.dev/297375964"), "userfaultfds that survive exec()");
38 return error!(ENOSYS);
39 };
40
41 let user_mode_only = raw_flags & UFFD_USER_MODE_ONLY != 0;
42 if !user_mode_only {
43 security::check_task_capable(current_task, CAP_SYS_PTRACE)?;
44 }
45 let uff_handle = UserFaultFile::new(locked, current_task, open_flags, user_mode_only)?;
46 current_task.add_file(locked, uff_handle, fd_flags)
47}
48
49pub use sys_userfaultfd as sys_arch32_userfaultfd;