Skip to content

Commit 47ff510

Browse files
committed
Wasm: Add support for directory access.
Due to the sandboxed nature of WebAssembly, by default WASM modules don't have any access to the underlying filesystem. There is however a capabilities based mechanism[0] for allowing such access. This adds a config option to the 'wasm' application type; 'access.filesystem' which takes an array of directory paths that are then made available to the WASM module. This access works recursively, i.e everything under a specific path is allowed access to. Example config might look like "access" { "filesystem": [ "/tmp", "/var/tmp" ] } The actual mechanism used allows directories to be mapped differently in the guest. But at the moment we don't support that and just map say /tmp to /tmp. This can be revisited if it's something users clamour for. Network sockets are another resource that may be controlled in this manner, for example there is a wasi_config_preopen_socket() function, however this requires the runtime to open the network socket then effectively pass this through to the guest. This is something that can be revisited in the future if users desire it. [0]: <https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-capabilities.md> Reviewed-by: Alejandro Colomar <[email protected]> Signed-off-by: Andrew Clayton <[email protected]>
1 parent e99854a commit 47ff510

File tree

6 files changed

+69
-1
lines changed

6 files changed

+69
-1
lines changed

src/nxt_application.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ typedef struct {
9999
const char *request_init_handler;
100100
const char *request_end_handler;
101101
const char *response_end_handler;
102+
103+
nxt_conf_value_t *access;
102104
} nxt_wasm_app_conf_t;
103105

104106

src/nxt_conf_validation.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_target_members[];
252252
static nxt_conf_vldt_object_t nxt_conf_vldt_php_common_members[];
253253
static nxt_conf_vldt_object_t nxt_conf_vldt_php_options_members[];
254254
static nxt_conf_vldt_object_t nxt_conf_vldt_php_target_members[];
255+
static nxt_conf_vldt_object_t nxt_conf_vldt_wasm_access_members[];
255256
static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[];
256257
static nxt_conf_vldt_object_t nxt_conf_vldt_app_limits_members[];
257258
static nxt_conf_vldt_object_t nxt_conf_vldt_app_processes_members[];
@@ -1081,12 +1082,27 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_wasm_members[] = {
10811082
}, {
10821083
.name = nxt_string("response_end_handler"),
10831084
.type = NXT_CONF_VLDT_STRING,
1085+
}, {
1086+
.name = nxt_string("access"),
1087+
.type = NXT_CONF_VLDT_OBJECT,
1088+
.validator = nxt_conf_vldt_object,
1089+
.u.members = nxt_conf_vldt_wasm_access_members,
10841090
},
10851091

10861092
NXT_CONF_VLDT_NEXT(nxt_conf_vldt_common_members)
10871093
};
10881094

10891095

1096+
static nxt_conf_vldt_object_t nxt_conf_vldt_wasm_access_members[] = {
1097+
{
1098+
.name = nxt_string("filesystem"),
1099+
.type = NXT_CONF_VLDT_ARRAY,
1100+
},
1101+
1102+
NXT_CONF_VLDT_END
1103+
};
1104+
1105+
10901106
static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
10911107
{
10921108
.name = nxt_string("type"),

src/nxt_main_process.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ static nxt_conf_map_t nxt_wasm_app_conf[] = {
369369
NXT_CONF_MAP_CSTRZ,
370370
offsetof(nxt_common_app_conf_t, u.wasm.response_end_handler),
371371
},
372+
{
373+
nxt_string("access"),
374+
NXT_CONF_MAP_PTR,
375+
offsetof(nxt_common_app_conf_t, u.wasm.access),
376+
},
372377
};
373378

374379

src/wasm/nxt_rt_wasmtime.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ nxt_wasmtime_get_function_exports(nxt_wasm_ctx_t *ctx)
247247
static int
248248
nxt_wasmtime_wasi_init(const nxt_wasm_ctx_t *ctx)
249249
{
250+
char **dir;
250251
wasi_config_t *wasi_config;
251252
wasmtime_error_t *error;
252253
nxt_wasmtime_ctx_t *rt_ctx = &nxt_wasmtime_ctx;
@@ -258,6 +259,10 @@ nxt_wasmtime_wasi_init(const nxt_wasm_ctx_t *ctx)
258259
wasi_config_inherit_stdout(wasi_config);
259260
wasi_config_inherit_stderr(wasi_config);
260261

262+
for (dir = ctx->dirs; dir != NULL && *dir != NULL; dir++) {
263+
wasi_config_preopen_dir(wasi_config, *dir, *dir);
264+
}
265+
261266
error = wasmtime_context_set_wasi(rt_ctx->ctx, wasi_config);
262267
if (error != NULL) {
263268
nxt_wasmtime_err_msg(error, NULL, "failed to instantiate WASI");

src/wasm/nxt_wasm.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,15 @@ nxt_wasm_start(nxt_task_t *task, nxt_process_data_t *data)
204204
nxt_unit_done(unit_ctx);
205205
NXT_WASM_DO_HOOK(NXT_WASM_FH_MODULE_END);
206206

207+
if (nxt_wasm_ctx.dirs != NULL) {
208+
char **p;
209+
210+
for (p = nxt_wasm_ctx.dirs; *p != NULL; p++) {
211+
nxt_free(*p);
212+
}
213+
nxt_free(nxt_wasm_ctx.dirs);
214+
}
215+
207216
nxt_wops->destroy(&nxt_wasm_ctx);
208217

209218
exit(EXIT_SUCCESS);
@@ -214,9 +223,11 @@ static nxt_int_t
214223
nxt_wasm_setup(nxt_task_t *task, nxt_process_t *process,
215224
nxt_common_app_conf_t *conf)
216225
{
217-
int err;
226+
int n, i, err;
227+
nxt_conf_value_t *dirs = NULL;
218228
nxt_wasm_app_conf_t *c;
219229
nxt_wasm_func_handler_t *fh;
230+
static nxt_str_t filesystem_str = nxt_string("filesystem");
220231

221232
c = &conf->u.wasm;
222233

@@ -237,6 +248,33 @@ nxt_wasm_setup(nxt_task_t *task, nxt_process_t *process,
237248
fh[NXT_WASM_FH_REQUEST_END].func_name = c->request_end_handler;
238249
fh[NXT_WASM_FH_RESPONSE_END].func_name = c->response_end_handler;
239250

251+
/* Get any directories to pass through to the WASM module */
252+
if (c->access != NULL) {
253+
dirs = nxt_conf_get_object_member(c->access, &filesystem_str, NULL);
254+
}
255+
256+
n = (dirs != NULL) ? nxt_conf_object_members_count(dirs) : 0;
257+
if (n == 0) {
258+
goto out_init;
259+
}
260+
261+
nxt_wasm_ctx.dirs = nxt_zalloc((n + 1) * sizeof(char *));
262+
if (nxt_slow_path(nxt_wasm_ctx.dirs == NULL)) {
263+
return NXT_ERROR;
264+
}
265+
266+
for (i = 0; i < n; i++) {
267+
nxt_str_t str;
268+
nxt_conf_value_t *value;
269+
270+
value = nxt_conf_get_array_element(dirs, i);
271+
nxt_conf_get_string(value, &str);
272+
273+
nxt_wasm_ctx.dirs[i] = nxt_zalloc(str.length + 1);
274+
memcpy(nxt_wasm_ctx.dirs[i], str.start, str.length);
275+
}
276+
277+
out_init:
240278
err = nxt_wops->init(&nxt_wasm_ctx);
241279
if (err) {
242280
exit(EXIT_FAILURE);

src/wasm/nxt_wasm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ struct nxt_wasm_ctx_s {
110110

111111
nxt_wasm_func_handler_t fh[NXT_WASM_FH_NR];
112112

113+
char **dirs;
114+
113115
nxt_unit_request_info_t *req;
114116

115117
uint8_t *baddr;

0 commit comments

Comments
 (0)