[译]安全的WebAssembly内存操做

做者:Lin Clark
译者:xlaoyu
英文原文:Memory in WebAssembly (and why it’s safer than you think)git

转载请注明出处,保留原文连接以及做者信息github


这是 WebAssembly 使用系列介绍的第二篇文章:web

  1. 使用JavaScript建立WebAssembly模块实例
  2. 安全的WebAssembly内存操做
  3. WebAssembly的导入类型 table 究竟是什么?

Memory(内存,内存都以内存称呼)在 WebAssembly 中的使用和在 JavaScript 中稍有不一样。在 WebAssembly 里,咱们能够直接访问原始字节,这可能会让一些人感到担心,但它实际上比你想象的更安全。数组

什么是内存对象?

当一个WebAssembly模块被实例化时,它须要一个内存对象。咱们能够建立一个新 WebAssembly.Memory 对象并将其传入。或者若是咱们没传,那么引擎将建立一个内存对象并自动将其附加到该实例上。浏览器

全部 JS 引擎都会在内部建立一个ArrayBuffer。ArrayBuffer 是 JS 引用的 JavaScript 对象,JS 替咱们为它分配内存。咱们告诉它须要多少内存,它会建立咱们须要大小的 ArrayBuffer 对象。安全

arraybuffer

数组的索引能够看做是内存地址。若是之后咱们须要更多的内存空间,能够执行一种叫作 增加 的操做来扩大数组。函数

使用 JavaScript 的对象 ArrayBuffer 来操控 WebAssembly 的内存,达成了两个目的:编码

  1. 使在 JS 和 WebAssembly 之间互相传递数据更简单
  2. 有助于内存管理的安全性

在 JS 和 WebAssembly 之间传递数据

由于 ArrayBuffer 也只是一个 JavaScript 对象,这意味着 JavaScript 有足够的能力能够去操做内存里的字节。基于这种方式,WebAssembly 和 JavaScript 能够共享内存并来回传递值。code

它们使用数组下标去定位内存块,而不是使用内存地址。cdn

例如,WebAssembly 能够把一个字符串放进内存里。首先把字符串编码为字节。。

encode

而后把字节放进数组中。

put-array

而后它会将第一个索引(整数)返回给 JavaScript,因此 JavaScript 能够将字节取出来并使用它们。

return-index

目前为止,大多数 JavaScript 引擎都没法直接使用字节来工做,因此咱们须要在 JS 这边使用某些方法把字节转化为有用的数据类型,好比字符串。

在某些浏览器中,咱们可使用 TextDecoderTextEncoder API。或者咱们能够像 Emscripten 那样在代码中加入辅助函数,帮助咱们完成这件事情。

use-bytes

以上是使用 JS 对象操做 WebAssembly 内存的第一个优势:能够直接经过内存互相传递数据

让内存访问更安全

使用 JavaScript 对象处理 WebAssembly 内存的另一个好处就是:安全性。经过帮助防止浏览器级内存泄漏并提供内存隔离,它使事情更安全。

内存泄漏

当咱们本身手动管理内存时,随时可能忘记清除它。这可能会致使系统内存不足最终内存溢出。

咱们想象一下,若是一个 WebAssembly 模块实例能够直接访问内存,而且在该实例执行完成退出上下文时忘记释放该内存,那么将会致使内存泄露。可是如今因为内存对象是一个 JavaScript 对象,它的存在将由垃圾回收器追踪着(尽管并无控制内容)。这意味着当 WebAssembly 模块实例离开执行上下文时,整个内存数组将会被回收掉。

gc

内存隔离

当人们得知 WebAssembly 模块能够直接访问内存时,这可能会让咱们有点紧张。咱们可能会觉得 WebAssembly 模块能够定位和访问到它们本该不能访问的内存,但事实并不是如此。

ArrayBuffer 对象边界会提供一个限制,这是 WebAssembly 模块能直接接触到的内存边界。

boundary

WebAssembly 能够直接获取该数组内部的字节,但它不能看到超出此数组边界的任何内容。

例如,内存中的任何其余JS对象(如全局window)都不能被 WebAssembly 访问。这对安全性很是重要。

不管什么时候在 WebAssembly 中进行读取或写操做时,引擎都会执行数组边界检查以确保地址位于 WebAssembly 实例的内存中。

若是代码尝试访问超出界限的地址,则引擎将引起异常,这保护了其他的内存。


下篇文章,咱们一块儿来看看什么是 WebAssembly 的 table 对象。

相关文章
相关标签/搜索