3个不稳定版本
0.2.1 | 2024年4月16日 |
---|---|
0.2.0 | 2024年4月5日 |
0.1.0 | 2024年4月4日 |
#308 in Unix APIs
每月113次下载
34KB
445 行
seccomp-stream
seccomp在内核版本5.0中由seccomp_unotify修改,增加了为seccomp事件添加用户空间通知器的功能。
已将其支持添加到libseccomp-rs,但它们的实现虽然完整,但却是阻塞的,因此不适合现代的异步Rust。
此crate旨在提供异步接收和回复这些通知的方式。
Cargo
cargo add seccomp-stream
或
seccomp-stream = "0.2"
使用方法
在接收通知后,您可以选择让系统调用通过并继续。然而,这却是不安全的,因为目标进程可能已经通过信号修改了参数。
有关更多信息,请参阅seccomp_unotify的手册页。
let mut stream = NotificationStream::new(fd).expect("Failed to construct NotificationStream");
while let Some(notification) = stream.next().await {
unsafe { stream.send_continue(notification) }.unwrap();
}
或者,您可以选择在检查参数的有效性后,用目标进程替换系统调用。
虽然您可以使用Notification::open
打开内存进行读写,但您会暴露自己于竞争条件。
根据手册页的说明,写入目标内存是绝对不安全的。
let mut stream = NotificationStream::new(fd).expect("Failed to construct NotificationStream");
while let Some(notification) = stream.next().await {
// Interact with the process in some way here
stream
.send(notification, ResponseType::Success(0))
.expect("Failed to send response");
}
第三种选择是注入错误,阻止系统调用进一步进行。这将迫使目标进程使用其自己的错误处理。
let mut stream = NotificationStream::new(fd).expect("Failed to construct NotificationStream");
while let Some(notification) = stream.next().await {
stream
.send(notification, ResponseType::RawError(libc::EPERM))
.expect("Failed to send response");
}
安全性
安装过滤器后,seccomp将返回一个文件描述符,可以用来通过epoll进行交互。
一旦epoll表明文件描述符可读,对ioctl的调用将不会阻塞。在其他任何情况下,调用都将阻塞。您可以选择以这种方式使用此库,但请注意混合阻塞和非阻塞方法可能会破坏阻塞保证。
之前概述的某些不应该做的事情。
- 粗心大意地读取另一个进程的内存
- 假设目标进程已完全停止
- 写入另一个进程的内存
如果你信任目标进程,你可以选择仍然做这些事情,并且事情(可能)不会失控。
兼容性
该库需要以下内容存在
- Linux内核版本5.0或更高
- libseccomp和libseccomp-dev版本2.5或更高
- 较新的Rust版本
依赖项
~3-11MB
~104K SLoC