#![forbid(unsafe_code)]
use libseccomp::ScmpNotifResp;
use memchr::memchr;
use nix::errno::Errno;
use crate::{
confine::is_valid_ptr, log::log_untrusted_buf, proc::proc_comm, req::UNotifyEventRequest, warn,
};
#[expect(clippy::cognitive_complexity)]
pub(crate) fn sys_prctl(request: UNotifyEventRequest) -> ScmpNotifResp {
syscall_handler!(request, |request: UNotifyEventRequest| {
let req = request.scmpreq;
#[expect(clippy::cast_possible_truncation)]
let op = req.data.args[0] as u32;
assert_eq!(op, libc::PR_SET_NAME as u32);
let ptr = req.data.args[1];
if !is_valid_ptr(ptr, req.data.arch) {
return Err(Errno::EFAULT);
}
let sandbox = request.get_sandbox();
if !sandbox.log_prctl() {
return Ok(request.return_syscall(0));
}
drop(sandbox);
let mut buf = [0u8; 15];
let name = match request.read_mem(&mut buf, ptr, 15) {
Ok(len) => {
let nil = memchr(0, &buf[..len]).unwrap_or(len);
&buf[..nil]
}
Err(errno) => return Err(errno),
};
match proc_comm(req.pid()) {
Ok(comm) if comm.is_equal(name) => {}
Ok(comm) => {
let (name, hex) = log_untrusted_buf(name);
warn!("ctx": "change_process_name",
"msg": format!("attempt to change process name from `{comm}' to `{name}' prevented"),
"tip": "use log/verbose:0 to silence, trace/allow_unsafe_prctl:1 to allow",
"sys": request.syscall, "name": name, "hex": hex, "comm": comm, "pid": req.pid,
"req": &request);
}
Err(_) => {
let (name, hex) = log_untrusted_buf(name);
warn!("ctx": "change_process_name",
"msg": format!("attempt to change process name to `{name}' prevented"),
"tip": "use log/verbose:0 to silence, trace/allow_unsafe_prctl:1 to allow",
"sys": request.syscall, "name": name, "hex": hex, "pid": req.pid,
"req": &request);
}
}
Ok(request.return_syscall(0))
})
}