SkillAgentSearch skills...

Uvwasi

WASI syscall API built atop libuv

Install / Use

/learn @nodejs/Uvwasi
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

uvwasi

This project does not currently provide the comprehensive file system security properties provided by some WASI runtimes. Full support for secure file system sandboxing may or may not be implemented in future. In the mean time, do not rely on it to run untrusted code.

uvwasi implements the [WASI][] system call API, so that WebAssembly runtimes can easily implement WASI calls. Under the hood, uvwasi leverages [libuv][] where possible for maximum portability.

                              |
WebAssembly code              |      WebAssembly application code
                              |                 |
                              |                 v
                              | WASI syscalls (inserted by compiler toolchain)
                              |                 |
------------------------------+                 |
                              |                 v
WebAssembly runtime (Node.js) |    uvwasi (implementation of WASI)
                              |                 |
                              |                 v
                              |               libuv
                              |                 |
                              |                 v
                              |        platform-specific calls
                              |

(Hence uvwasi isn't for making C-programs-that-use-libuv-APIs execute on WASI runtimes. That would either be a new platform added by libuv, or done through POSIX emulation by the Emscripten or wasi-sdk toolchains.)

Building Locally

To build with CMake:

$ mkdir -p out/cmake ; cd out/cmake   # create build directory
$ cmake ../.. -DBUILD_TESTING=ON      # generate project with test
$ cmake --build .                     # build
$ ctest -C Debug --output-on-failure  # run tests

Example Usage

#include <stdlib.h>
#include <assert.h>
#include "uv.h"
#include "uvwasi.h"

int main(void) {
  uvwasi_t uvwasi;
  uvwasi_options_t init_options;
  uvwasi_errno_t err;

  /* Setup the initialization options. */
  init_options.in = 0;
  init_options.out = 1;
  init_options.err = 2;
  init_options.fd_table_size = 3;
  init_options.argc = 3;
  init_options.argv = calloc(3, sizeof(char*));
  init_options.argv[0] = "--foo=bar";
  init_options.argv[1] = "-baz";
  init_options.argv[2] = "100";
  init_options.envp = NULL;
  init_options.preopenc = 1;
  init_options.preopens = calloc(1, sizeof(uvwasi_preopen_t));
  init_options.preopens[0].mapped_path = "/var";
  init_options.preopens[0].real_path = ".";
  init_options.allocator = NULL;

  /* Initialize the sandbox. */
  err = uvwasi_init(&uvwasi, &init_options);
  assert(err == UVWASI_ESUCCESS);

  /* TODO(cjihrig): Show an example system call or two. */

  /* Clean up resources. */
  uvwasi_destroy(&uvwasi);
  return 0;
}

API

The WASI API is versioned. This documentation is based on the WASI [preview 1][] snapshot. uvwasi implements the WASI system call API with the following additions/modifications:

  • Each system call takes an additional uvwasi_t* as its first argument. The uvwasi_t is the sandbox under which system calls are issued. Each uvwasi_t can have different command line arguments, environment variables, preopened directories, file descriptor mappings, etc. This allows one controlling process to host multiple WASI applications simultaneously.
  • Each system call returns a uvwasi_errno_t. This appears to be expected of WASI system calls, but it is not explicitly part of the official API docs. This detail is explicitly documented here.
  • Additional functions and data types are provided for interacting with WASI sandboxes and the uvwasi library. These APIs are documented in the Unofficial APIs section below.

Unofficial APIs

This section contains data types and functions for working with uvwasi. They are not part of the official WASI API, but are used to embed uvwasi.

<a href="#version_major" name="version_major"></a>UVWASI_VERSION_MAJOR

The major release version of the uvwasi library. uvwasi follows semantic versioning. Changes to this value represent breaking changes in the public API.

<a href="#version_minor" name="version_minor"></a>UVWASI_VERSION_MINOR

The minor release version of the uvwasi library. uvwasi follows semantic versioning. Changes to this value represent feature additions in the public API.

<a href="#version_patch" name="version_patch"></a>UVWASI_VERSION_PATCH

The patch release version of the uvwasi library. uvwasi follows semantic versioning. Changes to this value represent bug fixes in the public API.

<a href="#version_hex" name="version_hex"></a>UVWASI_VERSION_HEX

The major, minor, and patch versions of the uvwasi library encoded as a single integer value.

<a href="#version_string" name="version_string"></a>UVWASI_VERSION_STRING

The major, minor, and patch versions of the uvwasi library encoded as a version string.

<a href="#version_wasi" name="version_wasi"></a>UVWASI_VERSION_WASI

The version of the WASI API targeted by uvwasi.

<a href="#uvwasi_t" name="uvwasi_t"></a>uvwasi_t

An individual WASI sandbox instance.

typedef struct uvwasi_s {
  struct uvwasi_fd_table_t fds;
  uvwasi_size_t argc;
  char** argv;
  char* argv_buf;
  uvwasi_size_t argv_buf_size;
  uvwasi_size_t envc;
  char** env;
  char* env_buf;
  uvwasi_size_t env_buf_size;
} uvwasi_t;

<a href="#uvwasi_preopen_t" name="uvwasi_preopen_t"></a>uvwasi_preopen_t

A data structure used to map a directory path within a WASI sandbox to a directory path on the WASI host platform.

typedef struct uvwasi_preopen_s {
  char* mapped_path;
  char* real_path;
} uvwasi_preopen_t;

<a href="#uvwasi_options_t" name="uvwasi_options_t"></a>uvwasi_options_t

A data structure used to pass configuration options to uvwasi_init().

typedef struct uvwasi_options_s {
  uvwasi_size_t fd_table_size;
  uvwasi_size_t preopenc;
  uvwasi_preopen_t* preopens;
  uvwasi_size_t argc;
  char** argv;
  char** envp;
  uvwasi_fd_t in;
  uvwasi_fd_t out;
  uvwasi_fd_t err;
  const uvwasi_mem_t* allocator;
} uvwasi_options_t;

<a href="#uvwasi_init" name="uvwasi_init"></a>uvwasi_init()

Initializes a sandbox represented by a uvwasi_t using the options represented by a uvwasi_options_t.

Inputs:

  • <a href="#uvwasi_init.uvwasi" name="uvwasi_init.uvwasi"></a><code>__wasi_t <strong>uvwasi</strong></code>

    The sandbox to initialize.

  • <a href="#uvwasi_init.options" name="uvwasi_init.options"></a><code>__wasi_options_t <strong>options</strong></code>

    Configuration options used when initializing the sandbox.

Outputs:

  • None

Returns:

  • <a href="#uvwasi_init.return" name="uvwasi_init.return"></a><code>__wasi_errno_t <strong>errno</strong></code>

    A WASI errno.

<a href="#uvwasi_destroy" name="uvwasi_destroy"></a>uvwasi_destroy()

Cleans up resources related to a WASI sandbox. This function notably does not return an error code.

Inputs:

  • <a href="#uvwasi_destroy.uvwasi" name="uvwasi_destroy.uvwasi"></a><code>__wasi_t <strong>uvwasi</strong></code>

    The sandbox to clean up.

Outputs:

  • None

Returns:

  • None

System Calls

This section has been adapted from the official WASI API documentation.

<a href="#args_get" name="args_get"></a>uvwasi_args_get()

Read command-line argument data.

The sizes of the buffers should match that returned by uvwasi_args_sizes_get().

Inputs:

  • <a href="#args_get.argv" name="args_get.argv"></a><code>char **<strong>argv</strong></code>

    A pointer to a buffer to write the argument pointers.

  • <a href="#args_get.argv_buf" name="args_get.argv_buf"></a><code>char *<strong>argv_buf</strong></code>

    A pointer to a buffer to write the argument strin

View on GitHub
GitHub Stars260
CategoryDevelopment
Updated8d ago
Forks58

Languages

C

Security Score

95/100

Audited on Mar 27, 2026

No findings