use libseccomp::ScmpNotifResp;
use nix::{errno::Errno, sys::stat::Mode};
use crate::{
cookie::{safe_mkdirat, safe_umask},
kernel::{syscall_path_handler, to_mode},
lookup::FsFlags,
proc::proc_umask,
req::{PathArgs, SysArg, UNotifyEventRequest},
};
pub(crate) fn sys_mkdir(request: UNotifyEventRequest) -> ScmpNotifResp {
let req = request.scmpreq;
let mode = to_mode(req.data.args[1]);
let argv = &[SysArg {
path: Some(0),
fsflags: FsFlags::MISS_LAST | FsFlags::NO_FOLLOW_LAST | FsFlags::DOTLAST_EEXIST,
..Default::default()
}];
syscall_path_handler(request, "mkdir", argv, |path_args, request, sandbox| {
drop(sandbox); syscall_mkdir_handler(request, path_args, mode)
})
}
pub(crate) fn sys_mkdirat(request: UNotifyEventRequest) -> ScmpNotifResp {
let req = request.scmpreq;
let mode = to_mode(req.data.args[2]);
let argv = &[SysArg {
dirfd: Some(0),
path: Some(1),
fsflags: FsFlags::MISS_LAST | FsFlags::NO_FOLLOW_LAST | FsFlags::DOTLAST_EEXIST,
..Default::default()
}];
syscall_path_handler(request, "mkdirat", argv, |path_args, request, sandbox| {
drop(sandbox); syscall_mkdir_handler(request, path_args, mode)
})
}
fn syscall_mkdir_handler(
request: &UNotifyEventRequest,
args: PathArgs,
mode: Mode,
) -> Result<ScmpNotifResp, Errno> {
#[expect(clippy::disallowed_methods)]
let path = &args.0.as_ref().unwrap().path;
let req = request.scmpreq;
let mask = proc_umask(req.pid())?;
safe_umask(mask);
request.cache.add_sys_block(req, false)?;
let result = safe_mkdirat(path.dir(), path.base(), mode);
request.cache.del_sys_block(req.id)?;
result.map(|_| request.return_syscall(0))
}