Unsafe I/O

Rust 标准库提供了 I/O 安全性,保证程序持有私有的原始句柄(raw handle),其他部分无法访问它。但是 FromRawFd::from_raw_fd 是 Unsafe 的,所以在 Safe Rust中无法做到 File::from_raw(7) 这种事。 在这个文件描述符上面进行 I/O 操作,而这个文件描述符可能被程序的其他部分私自持有。


G.UNS.IO.01 在使用原始句柄的时候,要注意 I/O 安全性

【级别:必须】

必须严格按此规范执行。

【Lint 检测】

lint nameClippy 可检测Rustc 可检测Lint Group是否可定制
_nono_yes

【定制参考】

检测在 IO 时使用 as_raw_fd 调用时,警告开发者这是 Unsafe 的,要对传入的原始文件描述符的安全性进行考察。

【描述】

很多 API 通过接受 原始句柄 来进行 I/O 操作:


#![allow(unused)]
fn main() {
pub fn do_some_io<FD: AsRawFd>(input: &FD) -> io::Result<()> {
    some_syscall(input.as_raw_fd())
}
}

AsRawFd并没有限制as_raw_fd的返回值,所以do_some_io最终可以在任意的RawFd值上进行 I/O 操作。甚至可以写do_some_io(&7),因为RawFd本身实现了AsRawFd。这可能会导致程序访问错误的资源。甚至通过创建在其他部分私有的句柄别名来打破封装边界,导致一些诡异的 远隔作用(Action at a distance)。

远隔作用Action at a distance)是一种程式设计中的反模式,是指程式某一部分的行为会广泛的受到程式其他部分指令的影响,而且要找到影响其他程式的指令很困难,甚至根本无法进行。

在一些特殊的情况下,违反 I/O 安全甚至会导致内存安全。