واجهة نظام WebAssembly (WASI)
لا يوفر مُعامل node:wasi
حاليًا خصائص أمان نظام الملفات الشاملة التي توفرها بعض بيئات تشغيل WASI. قد يتم أو لا يتم تنفيذ الدعم الكامل لعزل نظام الملفات الآمن في المستقبل. في هذه الأثناء، لا تعتمد عليه لتشغيل التعليمات البرمجية غير الموثوقة.
رمز المصدر: lib/wasi.js
يوفر واجهة برمجة التطبيقات WASI تطبيقًا لمواصفات واجهة نظام WebAssembly. يمنح WASI تطبيقات WebAssembly حق الوصول إلى نظام التشغيل الأساسي عبر مجموعة من الوظائف الشبيهة بـ POSIX.
import { readFile } from 'node:fs/promises'
import { WASI } from 'node:wasi'
import { argv, env } from 'node:process'
const wasi = new WASI({
version: 'preview1',
args: argv,
env,
preopens: {
'/local': '/some/real/path/that/wasm/can/access',
},
})
const wasm = await WebAssembly.compile(await readFile(new URL('./demo.wasm', import.meta.url)))
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject())
wasi.start(instance)
'use strict'
const { readFile } = require('node:fs/promises')
const { WASI } = require('node:wasi')
const { argv, env } = require('node:process')
const { join } = require('node:path')
const wasi = new WASI({
version: 'preview1',
args: argv,
env,
preopens: {
'/local': '/some/real/path/that/wasm/can/access',
},
})
;(async () => {
const wasm = await WebAssembly.compile(await readFile(join(__dirname, 'demo.wasm')))
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject())
wasi.start(instance)
})()
لتشغيل المثال أعلاه، أنشئ ملف تنسيق نص WebAssembly جديدًا باسم demo.wat
:
(module
;; استيراد دالة fd_write WASI المطلوبة التي ستكتب متجهات الإدخال/الإخراج المعطاة إلى stdout
;; توقيع الدالة لـ fd_write هو:
;; (وصف الملف، *iovs، iovs_len، nwritten) -> يرجع عدد البايت المكتوبة
(import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32)))
(memory 1)
(export "memory" (memory 0))
;; كتابة 'hello world\n' إلى الذاكرة عند إزاحة 8 بايت
;; لاحظ سطر جديد في النهاية وهو مطلوب لظهور النص
(data (i32.const 8) "hello world\n")
(func $main (export "_start")
;; إنشاء متجه إدخال/إخراج جديد داخل ذاكرة خطية
(i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - هذا مؤشر إلى بداية سلسلة 'hello world\n'
(i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - طول سلسلة 'hello world\n'
(call $fd_write
(i32.const 1) ;; file_descriptor - 1 لـ stdout
(i32.const 0) ;; *iovs - المؤشر إلى مصفوفة iov، المخزنة في موقع الذاكرة 0
(i32.const 1) ;; iovs_len - نقوم بطباعة سلسلة واحدة مخزنة في iov - لذا واحدة.
(i32.const 20) ;; nwritten - مكان في الذاكرة لتخزين عدد البايت المكتوبة
)
drop ;; تجاهل عدد البايت المكتوبة من أعلى المكدس
)
)
استخدم wabt لترجمة .wat
إلى .wasm
wat2wasm demo.wat
الأمان
[السجل]
الإصدار | التغييرات |
---|---|
v21.2.0, v20.11.0 | توضيح خصائص أمان WASI. |
v21.2.0, v20.11.0 | تمت الإضافة في: v21.2.0, v20.11.0 |
يوفر WASI نموذجًا قائمًا على الإمكانيات، حيث يتم تزويد التطبيقات بإمكانيات مخصصة خاصة بها env
, preopens
, stdin
, stdout
, stderr
, و exit
.
لا يوفر نموذج التهديد الحالي لـ Node.js حماية آمنة كما هو موجود في بعض بيئات تشغيل WASI.
في حين يتم دعم ميزات الإمكانات، إلا أنها لا تشكل نموذجًا أمنيًا في Node.js. على سبيل المثال، يمكن تجاوز حماية نظام الملفات باستخدام تقنيات مختلفة. يستكشف المشروع إمكانية إضافة هذه الضمانات الأمنية في المستقبل.
الفئة: WASI
تمت الإضافة في: v13.3.0, v12.16.0
توفر فئة WASI
واجهة برمجة تطبيقات نظام WASI وطرق مساعدة إضافية للعمل مع التطبيقات القائمة على WASI. يمثل كل مثيل WASI
بيئة مميزة.
new WASI([options])
[السجل]
الإصدار | التغييرات |
---|---|
v20.1.0 | تم تغيير القيمة الافتراضية لـ returnOnExit إلى true. |
v20.0.0 | أصبح خيار الإصدار مطلوبًا الآن وليس له قيمة افتراضية. |
v19.8.0 | تمت إضافة حقل الإصدار إلى الخيارات. |
v13.3.0, v12.16.0 | تمت الإضافة في: v13.3.0, v12.16.0 |
options
<Object>args
<Array> مصفوفة من السلاسل التي سيرى تطبيق WebAssembly أنها وسيطات سطر الأوامر. الوسيطة الأولى هي المسار الظاهري لأمر WASI نفسه. الافتراضي:[]
.env
<Object> كائن مشابه لـprocess.env
سيرى تطبيق WebAssembly أنه بيئته. الافتراضي:{}
.preopens
<Object> يمثل هذا الكائن بنية الدليل المحلي لتطبيق WebAssembly. تُعامل مفاتيح السلسلة فيpreopens
على أنها أدلة داخل نظام الملفات. القيم المقابلة فيpreopens
هي المسارات الحقيقية لتلك الأدلة على جهاز المضيف.returnOnExit
<boolean> بشكل افتراضي، عندما تستدعي تطبيقات WASI__wasi_proc_exit()
، ستعيدwasi.start()
رمز الخروج المحدد بدلاً من إنهاء العملية. سيؤدي تعيين هذا الخيار إلىfalse
إلى إنهاء عملية Node.js برمز الخروج المحدد بدلاً من ذلك. الافتراضي:true
.stdin
<integer> مُعرّف الملف المستخدم كمدخل قياسي في تطبيق WebAssembly. الافتراضي:0
.stdout
<integer> مُعرّف الملف المستخدم كمخرج قياسي في تطبيق WebAssembly. الافتراضي:1
.stderr
<integer> مُعرّف الملف المستخدم كخطأ قياسي في تطبيق WebAssembly. الافتراضي:2
.version
<string> إصدار WASI المطلوب. الإصدارات المدعومة حاليًا هيunstable
وpreview1
. هذا الخيار إلزامي.
wasi.getImportObject()
تم الإضافة في: v19.8.0
إرجاع كائن استيراد يمكن تمريره إلى WebAssembly.instantiate()
إذا لم تكن هناك حاجة إلى استيرادات WASM أخرى بخلاف تلك التي يوفرها WASI.
إذا تم تمرير الإصدار unstable
إلى المُنشئ، فسيتم إرجاع ما يلي:
{ wasi_unstable: wasi.wasiImport }
إذا تم تمرير الإصدار preview1
إلى المُنشئ أو لم يتم تحديد أي إصدار، فسيتم إرجاع ما يلي:
{ wasi_snapshot_preview1: wasi.wasiImport }
wasi.start(instance)
تم الإضافة في: v13.3.0، v12.16.0
instance
<WebAssembly.Instance>
محاولة بدء تنفيذ instance
كأمر WASI من خلال استدعاء تصديره _start()
. إذا لم يحتوي instance
على تصدير _start()
، أو إذا كان instance
يحتوي على تصدير _initialize()
، فسيتم طرح استثناء.
يتطلب start()
أن يقوم instance
بتصدير ذاكرة من نوع WebAssembly.Memory
باسم memory
. إذا لم يكن لدى instance
تصدير memory
، فسيتم طرح استثناء.
إذا تم استدعاء start()
أكثر من مرة، فسيتم طرح استثناء.
wasi.initialize(instance)
تم الإضافة في: v14.6.0، v12.19.0
instance
<WebAssembly.Instance>
محاولة تهيئة instance
كجهاز استقبال WASI من خلال استدعاء تصديره _initialize()
، إذا كان موجودًا. إذا كان instance
يحتوي على تصدير _start()
، فسيتم طرح استثناء.
يتطلب initialize()
أن يقوم instance
بتصدير ذاكرة من نوع WebAssembly.Memory
باسم memory
. إذا لم يكن لدى instance
تصدير memory
، فسيتم طرح استثناء.
إذا تم استدعاء initialize()
أكثر من مرة، فسيتم طرح استثناء.
wasi.wasiImport
تم الإضافة في: v13.3.0، v12.16.0
wasiImport
هو كائن ينفذ واجهة برمجة تطبيقات نظام استدعاء WASI. يجب تمرير هذا الكائن كاستيراد wasi_snapshot_preview1
أثناء إنشاء مثيل WebAssembly.Instance
.