La memoria en WebAssembly (y por qué es mas seguro de lo que piensas)

25 noviembre, 2017 1:42 por

Esta es una traducción del artículo original publicado en el blog de Mozilla Hacks.

La memoria en WebAssembly funciona un poco distinto a como se hace en JavaScript. Con WebAssembly, tienes acceso directo a los bytes en crudo… y eso le preocupa a muchas personas. Pero en realidad es más seguro de lo que piensas.

¿Qué es un objeto de memoria?

Cuando un módulo de WebAssembly es instanciado, necesita un objeto de memoria. Puedes crear un nuevo WebAssembly.Memory y pasar ese objeto. O, si no lo haces, un objeto de memoria se creará y se adjuntará a la instancia automáticamente.

Todos lo que el motor de JS hará internamente es crear un ArrayBuffer (el cual está explicado en otro artículo). El ArrayBuffer es un objeto de JavaScript  referenciado desde JS. JA asigna la memoria por tí. Puedes decirle cuanta memoria vas a necesitar y creará un ArrayBuffer de ese tamaño.

"Un WebAssembly.Memory, por favor."

Los índices del arreglo pueden ser tratado como si fuesen direcciones de memoria. Si necesitas más memoria,  puedes hacer algo llamado growing (crecer) para agrandar el arreglo.

Manipular la memoria de WebAssembly como un ArrayBuffer— como un objeto de Javascript — permite hacer 2 cosas:

  1. Facilita el paso de valores entre JS y WebAssembly.
  2. Ayuda a manejar la memoria de forma segura.

Pasando valores entre JS y WebAssembly

Debido a que solo es un objeto JavaScript, significa que JavaScript puede acceder a estos bytes de memoria. De esta forma, WebAssembly y JavaScript pueden compartir memoria y pasarse valores entre ambos.

En vez de usar una dirección memoria, utilizan un índice del arreglo para acceder a cada posición.

Por ejemplo, el WebAssembly puede poner un string en memoria. Éste se codificaría en bytes…

…y entonces poner esos bytes en el arreglo.

Y luego esto retornaría el primer índice, el cual es un número entero, para JavaScript. Así que JavaScript puede obtener estos bytes y usarlos.

Ahora, la mayor parte de JavaScript no sabe cómo trabajar directamente con bytes. Así que necesitarás procesar en el lado de JavaScript, como lo hiciste en el lado de WebAssembly, para convertir de  bytes a valores mas útiles como cadenas de texto.

En algunos navegadores, puedes usar las APIs de TextDecoder y TextEncoder. O puedes añadir funciones de ayuda a tu archivo .js. Por ejemplo, una herramienta como Emscripten puede agregar funciones para codificar y decodificar.

Así que ese es el primer beneficio de tener la memoria de WebAssembly como un objeto de JS. WebAssembly y JavaScript podrán pasar valores entre sí a través de la memoria.

Haciendo el acceso a memoria más seguro

Existe otro beneficio de tener la memoria de WebAssembly como si fuese un objeto de JavaScript: seguridad. Lo hace más seguro para ayudar a prevenir desbordamiento de memoria a nivel del navegador y ofreciendo aislamiento de memoria.

Desbordes de memoria

Cuando administras tú mismo la memoria, existe la posibilidad de olvidar de limpiar. Esto puede causar que el sistema se quede sin memoria.

Si la instancia de módulo de WebAssembly tiene acceso directo a la memoria, y se le olvida liberarla antes de que se salga del ámbito, entonces el navegador podría desbordar memoria.

Pero como el objeto de memoria es un objeto de JavaScript, el mismo es monitoreado por el recolector de basura (aunque su contenido no lo es).

Esto significa que si la memoria de la instancia de WebAssembly se sale del ámbito, todo el arreglo de memoria puede ser recolectado y liberado.

Aislamiento de la Memoria

Cuando la gente escucha que WebAssembly te puede dar acceso directo a memoria, suelen ponerse nerviosos. Piensan que un módulo maligno de WebAssembly puede ir a revisar en partes de la memoria donde debería. Pero ese no es el caso.

Los límites de ArrayBuffer poseen un límite, que es lo que el módulo de WebAssembly puede tocar directamente.

Puede acceder directamente a los bytes que están dentro del arreglo pero no puede ver mas allá de los límites del mismo.

Por ejemplo, cualquier otro objeto de JS que está en memoria, como window, no es accesible a WebAssembly. Eso es muy importante para la seguridad.

Cuando se da una carga o almacenamiento en WebAssembly, el motor hace un chequeo de los límites del arreglo para asegurarse que la dirección de memoria está dentro de la memoria de la instancia de WebAssembly.

Si el código intenta acceder una dirección más allá de los límites, el motor arrojará una excepción. Esto protege al resto de la memoria.

The following two tabs change content below.
Colaborador de Mozilla Venezuela e Hispano en las áreas de desarrollo y medios sociales, entre otros. También soy desarrollador Web, Skateboarder, Profesor universitario, jugador de Playstation y PC, usuario Linux, Blogger, Geek, entre otros.

Compartir artículo:

Start the discussion at foro.mozilla-hispano.org

  • ¡Participa!

    Firefox Friends »
    Agrega botones de Firefox en tu sitio web y comparte tu amor por Mozilla Firefox.
    Ayuda a otros usuarios en Twitter.
    Colabora con la comunidad »
    En Mozilla lo importante son las personas. Descubre cómo puedes colaborar.

    Boletín Firefox

    Suscríbete al boletín de novedades de Firefox.

  • Descargas

    Descarga los programas de Mozilla.

    Lo más visto

    cc-by-sa