gpt4 book ai didi

rust - 编译器通过禁止分配给借用的值来防止什么灾难?

转载 作者:行者123 更新时间:2023-11-29 08:12:40 35 4
gpt4 key购买 nike

来自 Programming in Rust (PDF) 的示例:

#[derive(Debug)]
enum IntOrString {
I(isize),
S(String),
}

fn corrupt_enum() {
let mut s = IntOrString::S(String::new());
match s {
IntOrString::I(_) => (),
IntOrString::S(ref p) => {
s = IntOrString::I(0xdeadbeef);
// Now p is a &String, pointing at memory
// that is an int of our choosing!
}
}
}

corrupt_enum();

编译器不允许这样做:

error[E0506]: cannot assign to `s` because it is borrowed
--> src/main.rs:13:17
|
12 | IntOrString::S(ref p) => {
| ----- borrow of `s` occurs here
13 | s = IntOrString::I(0xdeadbeef);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `s` occurs here

但假设确实如此;这是怎么回事

Now p is a &String, pointing at memory that is an int of our choosing!

是坏事吗?

最佳答案

让我们为所涉及的类型制定一个内存布局。 IntOrString 将有一个字节来确定它是哪个变体(0 = 数字,1 = 字符串),后跟 4 个字节一组 UTF-8 字符开头的数字或地址。

让我们在内存中的 0x100 处分配 s。变体位于 0x100,值位于 0x101、0x102、0x103、0x104。另外,假设值的内容是指针0xABCD;这是字符串的字节所在的位置。

当使用匹配臂 IntOrString::S(ref p) 时,p 将被设置为值 0x101 - 这是一个对该值的引用,该值从 0x101 开始。当您尝试使用 p 时,处理器将转到地址 0x101,读取值(地址),然后从该地址读取数据。

如果编译器允许您在此时更改s,那么新数据的新字节将替换存储在0x101中的值>。在示例中,存储在值中的“地址”现在将指向任意位置(0xDEADBEEF)。如果我们尝试使用“字符串”,我们将开始读取不太可能对应于 UTF-8 数据的内存字节。

这些都不是学术问题,这类问题可能会出现在格式良好的 C 程序中。在好的情况下,程序会崩溃。在糟糕的情况下,您可能会在不应该的情况下读取程序中的数据。甚至可以注入(inject) shellcode,使攻击者能够运行 他们 在您的程序中编写的代码。


请注意,上面的内存布局非常简化,而实际的 String 更大更复杂。

关于rust - 编译器通过禁止分配给借用的值来防止什么灾难?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36225868/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com