如何防止Rust程序释放(释放)它不拥有的C字节

问题描述 投票:2回答:1

libc有一个函数,该函数返回不应为free()d的字符串。可以从/etc/passwd读取用户的当前目录,但不应将其为free()d。如果我从指针创建字符串,程序将异常终止

free(): invalid pointer
Aborted (core dumped)

显然该代码不安全。

let pw = libc::getpwnam(username.as_ptr() as *const i8);
let cd = (*pw).pw_dir;
let len = libc::strlen(cd);
builder.current_dir(String::from_raw_parts(cd as *mut u8, len, len));

我可以mem::forget(s)字符串,但是会泄漏内存,至少必须将长度存储在某个位置。我只需要防止释放基础原始字节。项目是一台服务器,所以我不能忽略泄漏。

rust
1个回答
2
投票

String::from_raw_parts是在此处使用的错误功能。该函数只能用先前从String::from_raw_parts或同等方法获得的指针来调用,这显然在您的代码中不是这种情况,因为该字符串来自C库,甚至没有动态分配。

相反,应该使用String::into_raw_parts&str或为此目的设计的slice::from_raw_parts类型创建指向数据的slice::from_raw_parts。拥有str::from_utf8后,应将其复制到一个拥有的字符串中,然后使用该字符串调用str::from_utf8。用CStr调用CStr会编译,但是不安全,需要您证明该函数(及其调用的函数)从不调用&str

这里是一个例子:

builder.current_dir()

请注意,此代码实际上也不安全,因为它不能在多个线程中使用。您应该改用builder.current_dir(),或者更好的是,使用像&str那样的板条箱代替getpwnam

© www.soinside.com 2019 - 2024. All rights reserved.