提问人:Vasilii Rogin 提问时间:7/9/2019 更新时间:7/9/2019 访问量:341
浏览器如何保护进程内存免受 webassembly 编译代码的影响?
How browser protects process memory from webassembly compiled code?
问:
根据“分析 WebAssembly 与原生代码的性能”研究,WebAssembly 代码在 Chrome 中被编译成原生 x86 指令。据我了解,可以创建WS代码,该代码将访问随机地址的随机内存。 当然,如果 WA 尝试访问不属于进程的内存,则会出现段错误。但是,同时,JS 和 WA 在同一个进程中运行,不是吗? Chrome 如何保护 Javascript 内存免受 webassembly 的攻击?如果 WS 代码会找出内部 JS 结构的地址范围并对其进行修改怎么办?
答:
1赞
ColinE
7/9/2019
#1
WebAssembly 不能直接寻址到任何进程内存中,相反,它只允许在预定义的“线性内存”中读取/写入内存地址,webassembly 模块与其 JavaScript 主机共享这些内存地址。
所以不行,WebAssembly 不能访问随机地址的随机内存。
2赞
Andreas Rossberg
7/9/2019
#2
Wasm 代码不能直接访问物理内存,无论是在 Wasm 引擎本身内部,还是在进程中的其他任何地方。它只能访问其声明的“线性内存”数组中的内存,这就像访问一个大字节数组一样。
对此数组的越界访问不会出现段错误。取而代之的是,Wasm 的执行将被一个所谓的陷阱中止,这是 Wasm 级别的一种例外。引擎可以以任何他们喜欢的方式实现边界检查。在 32 位体系结构上,它通常是实际的地址比较。在 64 位架构上,引擎可以使用更高效的虚拟内存技术,这会导致硬件信号,然后引擎会捕获该信号并将其转换为陷阱。然而,在这种情况下,硬件故障是一个实现细节,无法通过 Wasm 代码观察到。
评论
0赞
Vasilii Rogin
7/12/2019
您回答了“它如何根据标准工作”。我的问题是“它是如何在浏览器中实现的”。浏览器将 WS 代码编译为原生 x86 指令。它如何检查输出 asm 代码不会超出边界“预定义线性内存”?WS 代码和 JS 代码在同一个进程中运行(线程?),对吧?至少他们应该这样做,因为他们有共同的记忆。所以,我的问题是关于“这个陷阱机制是如何在浏览器中实现的”。CPU 如何知道这部分指令只能访问进程内存的子集?
0赞
Andreas Rossberg
7/12/2019
我以为我在第二段中解释一下?即,通过编译显式边界检查或拦截硬件信号。
0赞
Vasilii Rogin
7/13/2019
我还是不明白。我打开 mbebenita.github.io/WasmExplorer,我写了这段代码:Complied asm output contains this line .这是否使这种“更有效的虚拟内存技术”?在 x64 架构上,浏览器使用一些仅保存 WS ASM 数据的 4gb 内存范围,这是对的吗?C char test() { char *p = (char *)(0x0); return p[0xAABBCC]; };
movsx eax, byte ptr [r15 + 0xaabbcc]
r15
0赞
Andreas Rossberg
7/14/2019
是的,r15 指向内存后备存储的基址,这是一个 8 GiB 的地址范围,其开头是当前大小的内存,其余部分是访问的未映射的红色区域,这将发出引擎捕获的内存故障的信号。(它必须是 8GiB,因为 Wasm 的内存指令使用 32 位索引和 32 位偏移量。
评论