Просмотр исходного кода

Implement ns lookup allowlist (#1420)

The ns-lookup accepts domain names as well as suffixes, e.g.:

```
--allow-resolve=* # allow all domain names
--allow-resolve=example.com # only allow example.com name resolution
--allow-resolve=example.com --allow-resolve=*.example.com # allow example.com and its subdomains' name resolution
```
Marcin Kolny 3 лет назад
Родитель
Сommit
9a04c21075

+ 5 - 3
core/iwasm/aot/aot_runtime.c

@@ -1042,9 +1042,11 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
                 module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
                 module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
                 module->wasi_args.env, module->wasi_args.env_count,
                 module->wasi_args.env, module->wasi_args.env_count,
                 module->wasi_args.addr_pool, module->wasi_args.addr_count,
                 module->wasi_args.addr_pool, module->wasi_args.addr_count,
-                module->wasi_args.argv, module->wasi_args.argc,
-                module->wasi_args.stdio[0], module->wasi_args.stdio[1],
-                module->wasi_args.stdio[2], error_buf, error_buf_size))
+                module->wasi_args.ns_lookup_pool,
+                module->wasi_args.ns_lookup_count, module->wasi_args.argv,
+                module->wasi_args.argc, module->wasi_args.stdio[0],
+                module->wasi_args.stdio[1], module->wasi_args.stdio[2],
+                error_buf, error_buf_size))
             goto fail;
             goto fail;
     }
     }
 #endif
 #endif

+ 95 - 52
core/iwasm/common/wasm_runtime_common.c

@@ -2319,12 +2319,8 @@ wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module,
 
 
 #if WASM_ENABLE_LIBC_WASI != 0
 #if WASM_ENABLE_LIBC_WASI != 0
 
 
-void
-wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
-                              uint32 dir_count, const char *map_dir_list[],
-                              uint32 map_dir_count, const char *env_list[],
-                              uint32 env_count, char *argv[], int argc,
-                              int stdinfd, int stdoutfd, int stderrfd)
+static WASIArguments *
+get_wasi_args_from_module(wasm_module_t module)
 {
 {
     WASIArguments *wasi_args = NULL;
     WASIArguments *wasi_args = NULL;
 
 
@@ -2337,6 +2333,18 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
         wasi_args = &((AOTModule *)module)->wasi_args;
         wasi_args = &((AOTModule *)module)->wasi_args;
 #endif
 #endif
 
 
+    return wasi_args;
+}
+
+void
+wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
+                              uint32 dir_count, const char *map_dir_list[],
+                              uint32 map_dir_count, const char *env_list[],
+                              uint32 env_count, char *argv[], int argc,
+                              int stdinfd, int stdoutfd, int stderrfd)
+{
+    WASIArguments *wasi_args = get_wasi_args_from_module(module);
+
     if (wasi_args) {
     if (wasi_args) {
         wasi_args->dir_list = dir_list;
         wasi_args->dir_list = dir_list;
         wasi_args->dir_count = dir_count;
         wasi_args->dir_count = dir_count;
@@ -2367,16 +2375,7 @@ void
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
                                 uint32 addr_pool_size)
                                 uint32 addr_pool_size)
 {
 {
-    WASIArguments *wasi_args = NULL;
-
-#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
-    if (module->module_type == Wasm_Module_Bytecode)
-        wasi_args = &((WASMModule *)module)->wasi_args;
-#endif
-#if WASM_ENABLE_AOT != 0
-    if (module->module_type == Wasm_Module_AoT)
-        wasi_args = &((AOTModule *)module)->wasi_args;
-#endif
+    WASIArguments *wasi_args = get_wasi_args_from_module(module);
 
 
     if (wasi_args) {
     if (wasi_args) {
         wasi_args->addr_pool = addr_pool;
         wasi_args->addr_pool = addr_pool;
@@ -2384,13 +2383,67 @@ wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
     }
     }
 }
 }
 
 
+void
+wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module,
+                                     const char *ns_lookup_pool[],
+                                     uint32 ns_lookup_pool_size)
+{
+    WASIArguments *wasi_args = get_wasi_args_from_module(module);
+
+    if (wasi_args) {
+        wasi_args->ns_lookup_pool = ns_lookup_pool;
+        wasi_args->ns_lookup_count = ns_lookup_pool_size;
+    }
+}
+
 #if WASM_ENABLE_UVWASI == 0
 #if WASM_ENABLE_UVWASI == 0
+static bool
+copy_string_array(const char *array[], uint32 array_size, char **buf_ptr,
+                  char ***list_ptr, uint64 *out_buf_size)
+{
+    uint64 buf_size = 0, total_size;
+    uint32 buf_offset = 0, i;
+    char *buf = NULL, **list = NULL;
+
+    for (i = 0; i < array_size; i++)
+        buf_size += strlen(array[i]) + 1;
+
+    /* We add +1 to generate null-terminated array of strings */
+    total_size = sizeof(char *) * (uint64)array_size + 1;
+    if (total_size >= UINT32_MAX
+        || (total_size > 0 && !(list = wasm_runtime_malloc((uint32)total_size)))
+        || buf_size >= UINT32_MAX
+        || (buf_size > 0 && !(buf = wasm_runtime_malloc((uint32)buf_size)))) {
+
+        if (buf)
+            wasm_runtime_free(buf);
+        if (list)
+            wasm_runtime_free(list);
+        return false;
+    }
+
+    for (i = 0; i < array_size; i++) {
+        list[i] = buf + buf_offset;
+        bh_strcpy_s(buf + buf_offset, (uint32)buf_size - buf_offset, array[i]);
+        buf_offset += (uint32)(strlen(array[i]) + 1);
+    }
+    list[array_size] = NULL;
+
+    *list_ptr = list;
+    *buf_ptr = buf;
+    if (out_buf_size)
+        *out_buf_size = buf_size;
+
+    return true;
+}
+
 bool
 bool
 wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
 wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
                        const char *dir_list[], uint32 dir_count,
                        const char *dir_list[], uint32 dir_count,
                        const char *map_dir_list[], uint32 map_dir_count,
                        const char *map_dir_list[], uint32 map_dir_count,
                        const char *env[], uint32 env_count,
                        const char *env[], uint32 env_count,
                        const char *addr_pool[], uint32 addr_pool_size,
                        const char *addr_pool[], uint32 addr_pool_size,
+                       const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
                        char *argv[], uint32 argc, int stdinfd, int stdoutfd,
                        char *argv[], uint32 argc, int stdinfd, int stdoutfd,
                        int stderrfd, char *error_buf, uint32 error_buf_size)
                        int stderrfd, char *error_buf, uint32 error_buf_size)
 {
 {
@@ -2399,8 +2452,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
     char **argv_list = NULL;
     char **argv_list = NULL;
     char *env_buf = NULL;
     char *env_buf = NULL;
     char **env_list = NULL;
     char **env_list = NULL;
-    uint64 argv_buf_size = 0, env_buf_size = 0, total_size;
-    uint32 argv_buf_offset = 0, env_buf_offset = 0;
+    char *ns_lookup_buf = NULL;
+    char **ns_lookup_list = NULL;
+    uint64 argv_buf_size = 0, env_buf_size = 0;
     struct fd_table *curfds = NULL;
     struct fd_table *curfds = NULL;
     struct fd_prestats *prestats = NULL;
     struct fd_prestats *prestats = NULL;
     struct argv_environ_values *argv_environ = NULL;
     struct argv_environ_values *argv_environ = NULL;
@@ -2434,50 +2488,20 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
 #endif
 #endif
 
 
     /* process argv[0], trip the path and suffix, only keep the program name */
     /* process argv[0], trip the path and suffix, only keep the program name */
-    for (i = 0; i < argc; i++)
-        argv_buf_size += strlen(argv[i]) + 1;
-
-    total_size = sizeof(char *) * (uint64)argc;
-    if (total_size >= UINT32_MAX
-        || (total_size > 0
-            && !(argv_list = wasm_runtime_malloc((uint32)total_size)))
-        || argv_buf_size >= UINT32_MAX
-        || (argv_buf_size > 0
-            && !(argv_buf = wasm_runtime_malloc((uint32)argv_buf_size)))) {
+    if (!copy_string_array((const char **)argv, argc, &argv_buf, &argv_list,
+                           &argv_buf_size)) {
         set_error_buf(error_buf, error_buf_size,
         set_error_buf(error_buf, error_buf_size,
                       "Init wasi environment failed: allocate memory failed");
                       "Init wasi environment failed: allocate memory failed");
         goto fail;
         goto fail;
     }
     }
 
 
-    for (i = 0; i < argc; i++) {
-        argv_list[i] = argv_buf + argv_buf_offset;
-        bh_strcpy_s(argv_buf + argv_buf_offset,
-                    (uint32)argv_buf_size - argv_buf_offset, argv[i]);
-        argv_buf_offset += (uint32)(strlen(argv[i]) + 1);
-    }
-
-    for (i = 0; i < env_count; i++)
-        env_buf_size += strlen(env[i]) + 1;
-
-    total_size = sizeof(char *) * (uint64)env_count;
-    if (total_size >= UINT32_MAX
-        || (total_size > 0
-            && !(env_list = wasm_runtime_malloc((uint32)total_size)))
-        || env_buf_size >= UINT32_MAX
-        || (env_buf_size > 0
-            && !(env_buf = wasm_runtime_malloc((uint32)env_buf_size)))) {
+    if (!copy_string_array(env, env_count, &env_buf, &env_list,
+                           &env_buf_size)) {
         set_error_buf(error_buf, error_buf_size,
         set_error_buf(error_buf, error_buf_size,
                       "Init wasi environment failed: allocate memory failed");
                       "Init wasi environment failed: allocate memory failed");
         goto fail;
         goto fail;
     }
     }
 
 
-    for (i = 0; i < env_count; i++) {
-        env_list[i] = env_buf + env_buf_offset;
-        bh_strcpy_s(env_buf + env_buf_offset,
-                    (uint32)env_buf_size - env_buf_offset, env[i]);
-        env_buf_offset += (uint32)(strlen(env[i]) + 1);
-    }
-
     if (!(curfds = wasm_runtime_malloc(sizeof(struct fd_table)))
     if (!(curfds = wasm_runtime_malloc(sizeof(struct fd_table)))
         || !(prestats = wasm_runtime_malloc(sizeof(struct fd_prestats)))
         || !(prestats = wasm_runtime_malloc(sizeof(struct fd_prestats)))
         || !(argv_environ =
         || !(argv_environ =
@@ -2579,6 +2603,13 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
         }
         }
     }
     }
 
 
+    if (!copy_string_array(ns_lookup_pool, ns_lookup_pool_size, &ns_lookup_buf,
+                           &ns_lookup_list, NULL)) {
+        set_error_buf(error_buf, error_buf_size,
+                      "Init wasi environment failed: allocate memory failed");
+        goto fail;
+    }
+
     wasi_ctx->curfds = curfds;
     wasi_ctx->curfds = curfds;
     wasi_ctx->prestats = prestats;
     wasi_ctx->prestats = prestats;
     wasi_ctx->argv_environ = argv_environ;
     wasi_ctx->argv_environ = argv_environ;
@@ -2587,6 +2618,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
     wasi_ctx->argv_list = argv_list;
     wasi_ctx->argv_list = argv_list;
     wasi_ctx->env_buf = env_buf;
     wasi_ctx->env_buf = env_buf;
     wasi_ctx->env_list = env_list;
     wasi_ctx->env_list = env_list;
+    wasi_ctx->ns_lookup_buf = ns_lookup_buf;
+    wasi_ctx->ns_lookup_list = ns_lookup_list;
 
 
     return true;
     return true;
 
 
@@ -2615,6 +2648,10 @@ fail:
         wasm_runtime_free(env_buf);
         wasm_runtime_free(env_buf);
     if (env_list)
     if (env_list)
         wasm_runtime_free(env_list);
         wasm_runtime_free(env_list);
+    if (ns_lookup_buf)
+        wasm_runtime_free(ns_lookup_buf);
+    if (ns_lookup_list)
+        wasm_runtime_free(ns_lookup_list);
     return false;
     return false;
 }
 }
 #else  /* else of WASM_ENABLE_UVWASI == 0 */
 #else  /* else of WASM_ENABLE_UVWASI == 0 */
@@ -2666,6 +2703,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
                        const char *map_dir_list[], uint32 map_dir_count,
                        const char *map_dir_list[], uint32 map_dir_count,
                        const char *env[], uint32 env_count,
                        const char *env[], uint32 env_count,
                        const char *addr_pool[], uint32 addr_pool_size,
                        const char *addr_pool[], uint32 addr_pool_size,
+                       const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
                        char *argv[], uint32 argc, int stdinfd, int stdoutfd,
                        char *argv[], uint32 argc, int stdinfd, int stdoutfd,
                        int stderrfd, char *error_buf, uint32 error_buf_size)
                        int stderrfd, char *error_buf, uint32 error_buf_size)
 {
 {
@@ -2842,6 +2880,11 @@ wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
             wasm_runtime_free(wasi_ctx->env_buf);
             wasm_runtime_free(wasi_ctx->env_buf);
         if (wasi_ctx->env_list)
         if (wasi_ctx->env_list)
             wasm_runtime_free(wasi_ctx->env_list);
             wasm_runtime_free(wasi_ctx->env_list);
+        if (wasi_ctx->ns_lookup_buf)
+            wasm_runtime_free(wasi_ctx->ns_lookup_buf);
+        if (wasi_ctx->ns_lookup_list)
+            wasm_runtime_free(wasi_ctx->ns_lookup_list);
+
         wasm_runtime_free(wasi_ctx);
         wasm_runtime_free(wasi_ctx);
     }
     }
 }
 }

+ 8 - 0
core/iwasm/common/wasm_runtime_common.h

@@ -363,6 +363,8 @@ typedef struct WASIContext {
     struct fd_prestats *prestats;
     struct fd_prestats *prestats;
     struct argv_environ_values *argv_environ;
     struct argv_environ_values *argv_environ;
     struct addr_pool *addr_pool;
     struct addr_pool *addr_pool;
+    char *ns_lookup_buf;
+    char **ns_lookup_list;
     char *argv_buf;
     char *argv_buf;
     char **argv_list;
     char **argv_list;
     char *env_buf;
     char *env_buf;
@@ -770,6 +772,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
                        const char *map_dir_list[], uint32 map_dir_count,
                        const char *map_dir_list[], uint32 map_dir_count,
                        const char *env[], uint32 env_count,
                        const char *env[], uint32 env_count,
                        const char *addr_pool[], uint32 addr_pool_size,
                        const char *addr_pool[], uint32 addr_pool_size,
+                       const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
                        char *argv[], uint32 argc, int stdinfd, int stdoutfd,
                        char *argv[], uint32 argc, int stdinfd, int stdoutfd,
                        int stderrfd, char *error_buf, uint32 error_buf_size);
                        int stderrfd, char *error_buf, uint32 error_buf_size);
 
 
@@ -786,6 +789,11 @@ wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst);
 WASM_RUNTIME_API_EXTERN void
 WASM_RUNTIME_API_EXTERN void
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
                                 uint32 addr_pool_size);
                                 uint32 addr_pool_size);
+
+WASM_RUNTIME_API_EXTERN void
+wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module,
+                                     const char *ns_lookup_pool[],
+                                     uint32 ns_lookup_pool_size);
 #endif /* end of WASM_ENABLE_LIBC_WASI */
 #endif /* end of WASM_ENABLE_LIBC_WASI */
 
 
 #if WASM_ENABLE_REF_TYPES != 0
 #if WASM_ENABLE_REF_TYPES != 0

+ 4 - 0
core/iwasm/include/wasm_export.h

@@ -365,6 +365,10 @@ WASM_RUNTIME_API_EXTERN void
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
 wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
                                 uint32_t addr_pool_size);
                                 uint32_t addr_pool_size);
 
 
+WASM_RUNTIME_API_EXTERN void
+wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module, const char *ns_lookup_pool[],
+                                     uint32_t ns_lookup_pool_size);
+
 /**
 /**
  * Instantiate a WASM module.
  * Instantiate a WASM module.
  *
  *

+ 2 - 0
core/iwasm/interpreter/wasm.h

@@ -320,6 +320,8 @@ typedef struct WASIArguments {
     /* in CIDR noation */
     /* in CIDR noation */
     const char **addr_pool;
     const char **addr_pool;
     uint32 addr_count;
     uint32 addr_count;
+    const char **ns_lookup_pool;
+    uint32 ns_lookup_count;
     char **argv;
     char **argv;
     uint32 argc;
     uint32 argc;
     int stdio[3];
     int stdio[3];

+ 5 - 3
core/iwasm/interpreter/wasm_runtime.c

@@ -1631,9 +1631,11 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
                 module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
                 module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
                 module->wasi_args.env, module->wasi_args.env_count,
                 module->wasi_args.env, module->wasi_args.env_count,
                 module->wasi_args.addr_pool, module->wasi_args.addr_count,
                 module->wasi_args.addr_pool, module->wasi_args.addr_count,
-                module->wasi_args.argv, module->wasi_args.argc,
-                module->wasi_args.stdio[0], module->wasi_args.stdio[1],
-                module->wasi_args.stdio[2], error_buf, error_buf_size)) {
+                module->wasi_args.ns_lookup_pool,
+                module->wasi_args.ns_lookup_count, module->wasi_args.argv,
+                module->wasi_args.argc, module->wasi_args.stdio[0],
+                module->wasi_args.stdio[1], module->wasi_args.stdio[2],
+                error_buf, error_buf_size)) {
             goto fail;
             goto fail;
         }
         }
     }
     }

+ 15 - 2
core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c

@@ -51,6 +51,8 @@ typedef struct WASIContext {
     struct fd_prestats *prestats;
     struct fd_prestats *prestats;
     struct argv_environ_values *argv_environ;
     struct argv_environ_values *argv_environ;
     struct addr_pool *addr_pool;
     struct addr_pool *addr_pool;
+    char *ns_lookup_buf;
+    char **ns_lookup_list;
     char *argv_buf;
     char *argv_buf;
     char **argv_list;
     char **argv_list;
     char *env_buf;
     char *env_buf;
@@ -92,6 +94,14 @@ wasi_ctx_get_addr_pool(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
     return wasi_ctx->addr_pool;
     return wasi_ctx->addr_pool;
 }
 }
 
 
+static inline char **
+wasi_ctx_get_ns_lookup_list(wasi_ctx_t wasi_ctx)
+{
+    if (!wasi_ctx)
+        return NULL;
+    return wasi_ctx->ns_lookup_list;
+}
+
 static wasi_errno_t
 static wasi_errno_t
 wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
 wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
 {
 {
@@ -1056,14 +1066,17 @@ wasi_sock_addr_resolve(wasm_exec_env_t exec_env, const char *host,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
     struct fd_table *curfds = NULL;
     struct fd_table *curfds = NULL;
+    char **ns_lookup_list = NULL;
 
 
     if (!wasi_ctx)
     if (!wasi_ctx)
         return __WASI_EACCES;
         return __WASI_EACCES;
 
 
     curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
     curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
+    ns_lookup_list = wasi_ctx_get_ns_lookup_list(wasi_ctx);
 
 
-    return wasi_ssp_sock_addr_resolve(curfds, host, service, hints, addr_info,
-                                      addr_info_size, max_info_size);
+    return wasi_ssp_sock_addr_resolve(curfds, ns_lookup_list, host, service,
+                                      hints, addr_info, addr_info_size,
+                                      max_info_size);
 }
 }
 
 
 static wasi_errno_t
 static wasi_errno_t

+ 1 - 1
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h

@@ -1038,7 +1038,7 @@ wasi_ssp_sock_bind(
 __wasi_errno_t
 __wasi_errno_t
 wasi_ssp_sock_addr_resolve(
 wasi_ssp_sock_addr_resolve(
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
-    struct fd_table *curfds,
+    struct fd_table *curfds, char **ns_lookup_list,
 #endif
 #endif
     const char *host, const char* service,
     const char *host, const char* service,
     __wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info,
     __wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info,

+ 30 - 1
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c

@@ -161,6 +161,31 @@ convert_errno(int error)
     return errors[error];
     return errors[error];
 }
 }
 
 
+static bool
+ns_lookup_list_search(char **list, const char *host)
+{
+    size_t host_len = strlen(host), suffix_len;
+
+    while (*list) {
+        if (*list[0] == '*') {
+            suffix_len = strlen(*list) - 1;
+            if (suffix_len <= host_len
+                && strncmp(host + host_len - suffix_len, *list + 1, suffix_len)
+                       == 0) {
+                return true;
+            }
+        }
+        else {
+            if (strcmp(*list, host) == 0) {
+                return true;
+            }
+        }
+        list++;
+    }
+
+    return false;
+}
+
 // Converts a POSIX timespec to a CloudABI timestamp.
 // Converts a POSIX timespec to a CloudABI timestamp.
 static __wasi_timestamp_t
 static __wasi_timestamp_t
 convert_timespec(const struct timespec *ts)
 convert_timespec(const struct timespec *ts)
@@ -3014,7 +3039,7 @@ wasi_ssp_sock_bind(
 __wasi_errno_t
 __wasi_errno_t
 wasi_ssp_sock_addr_resolve(
 wasi_ssp_sock_addr_resolve(
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
-    struct fd_table *curfds,
+    struct fd_table *curfds, char **ns_lookup_list,
 #endif
 #endif
     const char *host, const char *service, __wasi_addr_info_hints_t *hints,
     const char *host, const char *service, __wasi_addr_info_hints_t *hints,
     __wasi_addr_info_t *addr_info, __wasi_size_t addr_info_size,
     __wasi_addr_info_t *addr_info, __wasi_size_t addr_info_size,
@@ -3027,6 +3052,10 @@ wasi_ssp_sock_addr_resolve(
     size_t _max_info_size;
     size_t _max_info_size;
     size_t actual_info_size;
     size_t actual_info_size;
 
 
+    if (!ns_lookup_list_search(ns_lookup_list, host)) {
+        return __WASI_EACCES;
+    }
+
     if (!wamr_addr_info) {
     if (!wamr_addr_info) {
         return __WASI_ENOMEM;
         return __WASI_ENOMEM;
     }
     }

+ 8 - 0
doc/socket_api.md

@@ -64,6 +64,14 @@ should be announced first. Every IP address should be in CIRD notation.
 $ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
 $ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
 ```
 ```
 
 
+_iwasm_ also accepts list of domain names and domain name patterns for the address resolution via an option, `--allow-resolve`, to implement the capability control. Every domain that will be resolved using `sock_addr_resolve` needs to be added to the allowlist first.
+
+```bash
+$ iwasm --allow-resolve=*.example.com --allow-resolve=domain.com
+```
+
+The example above shows how to allow for resolving all `example.com`'s subdomains (e.g. `x.example.com`, `a.b.c.example.com`) and `domain.com` domain.
+
 Refer to [socket api sample](../samples/socket-api) for more details.
 Refer to [socket api sample](../samples/socket-api) for more details.
 
 
 ## Intel SGX support
 ## Intel SGX support

+ 13 - 0
language-bindings/go/wamr/module.go

@@ -132,3 +132,16 @@ func (self *Module) SetWasiAddrPool(addrPool [][]byte) {
     }
     }
     C.wasm_runtime_set_wasi_addr_pool(self.module, addrPoolPtr, addrPoolSize)
     C.wasm_runtime_set_wasi_addr_pool(self.module, addrPoolPtr, addrPoolSize)
 }
 }
+
+/* Set module's wasi domain lookup pool */
+func(self *Module) SetWasiNsLookupPool(nsLookupPool[][] byte)
+{
+    var nsLookupPoolPtr **C.char
+    var nsLookupPoolSize C.uint
+
+    if (nsLookupPool != nil) {
+        nsLookupPoolPtr = (**C.char)(unsafe.Pointer(&nsLookupPool[0]))
+        nsLookupPoolSize = C.uint(len(nsLookupPool))
+    }
+    C.wasm_runtime_set_wasi_ns_lookup_pool(self.module, nsLookupPoolPtr, nsLookupPoolSize)
+}

+ 50 - 29
product-mini/platforms/posix/main.c

@@ -26,49 +26,54 @@ print_help()
 {
 {
     printf("Usage: iwasm [-options] wasm_file [args...]\n");
     printf("Usage: iwasm [-options] wasm_file [args...]\n");
     printf("options:\n");
     printf("options:\n");
-    printf("  -f|--function name     Specify a function name of the module to run rather\n"
-           "                         than main\n");
+    printf("  -f|--function name       Specify a function name of the module to run rather\n"
+           "                           than main\n");
 #if WASM_ENABLE_LOG != 0
 #if WASM_ENABLE_LOG != 0
-    printf("  -v=n                   Set log verbose level (0 to 5, default is 2) larger\n"
-           "                         level with more log\n");
+    printf("  -v=n                     Set log verbose level (0 to 5, default is 2) larger\n"
+           "                           level with more log\n");
 #endif
 #endif
-    printf("  --stack-size=n         Set maximum stack size in bytes, default is 16 KB\n");
-    printf("  --heap-size=n          Set maximum heap size in bytes, default is 16 KB\n");
+    printf("  --stack-size=n           Set maximum stack size in bytes, default is 16 KB\n");
+    printf("  --heap-size=n            Set maximum heap size in bytes, default is 16 KB\n");
 #if WASM_ENABLE_FAST_JIT != 0
 #if WASM_ENABLE_FAST_JIT != 0
-    printf("  --jit-codecache-size=n Set fast jit maximum code cache size in bytes,\n");
-    printf("                         default is %u KB\n", FAST_JIT_DEFAULT_CODE_CACHE_SIZE / 1024);
+    printf("  --jit-codecache-size=n   Set fast jit maximum code cache size in bytes,\n");
+    printf("                           default is %u KB\n", FAST_JIT_DEFAULT_CODE_CACHE_SIZE / 1024);
 #endif
 #endif
-    printf("  --repl                 Start a very simple REPL (read-eval-print-loop) mode\n"
-           "                         that runs commands in the form of \"FUNC ARG...\"\n");
+    printf("  --repl                   Start a very simple REPL (read-eval-print-loop) mode\n"
+           "                           that runs commands in the form of \"FUNC ARG...\"\n");
 #if WASM_ENABLE_LIBC_WASI != 0
 #if WASM_ENABLE_LIBC_WASI != 0
-    printf("  --env=<env>            Pass wasi environment variables with \"key=value\"\n");
-    printf("                         to the program, for example:\n");
-    printf("                           --env=\"key1=value1\" --env=\"key2=value2\"\n");
-    printf("  --dir=<dir>            Grant wasi access to the given host directories\n");
-    printf("                         to the program, for example:\n");
-    printf("                           --dir=<dir1> --dir=<dir2>\n");
-    printf("  --addr-pool=<addrs>    Grant wasi access to the given network addresses in\n");
-    printf("                         CIRD notation to the program, seperated with ',',\n");
-    printf("                         for example:\n");
-    printf("                           --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
+    printf("  --env=<env>              Pass wasi environment variables with \"key=value\"\n");
+    printf("                           to the program, for example:\n");
+    printf("                             --env=\"key1=value1\" --env=\"key2=value2\"\n");
+    printf("  --dir=<dir>              Grant wasi access to the given host directories\n");
+    printf("                           to the program, for example:\n");
+    printf("                             --dir=<dir1> --dir=<dir2>\n");
+    printf("  --addr-pool=<addrs>      Grant wasi access to the given network addresses in\n");
+    printf("                           CIRD notation to the program, seperated with ',',\n");
+    printf("                           for example:\n");
+    printf("                             --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
+    printf("  --allow-resolve=<domain> Allow the lookup of the specific domain name or domain\n");
+    printf("                           name suffixes using a wildcard, for example:\n");
+    printf("                           --allow-resolve=example.com # allow the lookup of the specific domain\n");
+    printf("                           --allow-resolve=*.example.com # allow the lookup of all subdomains\n");
+    printf("                           --allow-resolve=* # allow any lookup\n");
 #endif
 #endif
 #if BH_HAS_DLFCN
 #if BH_HAS_DLFCN
-    printf("  --native-lib=<lib>     Register native libraries to the WASM module, which\n");
-    printf("                         are shared object (.so) files, for example:\n");
-    printf("                           --native-lib=test1.so --native-lib=test2.so\n");
+    printf("  --native-lib=<lib>       Register native libraries to the WASM module, which\n");
+    printf("                           are shared object (.so) files, for example:\n");
+    printf("                             --native-lib=test1.so --native-lib=test2.so\n");
 #endif
 #endif
 #if WASM_ENABLE_MULTI_MODULE != 0
 #if WASM_ENABLE_MULTI_MODULE != 0
-    printf("  --module-path=<path>   Indicate a module search path. default is current\n"
-           "                         directory('./')\n");
+    printf("  --module-path=<path>     Indicate a module search path. default is current\n"
+           "                           directory('./')\n");
 #endif
 #endif
 #if WASM_ENABLE_LIB_PTHREAD != 0
 #if WASM_ENABLE_LIB_PTHREAD != 0
-    printf("  --max-threads=n        Set maximum thread number per cluster, default is 4\n");
+    printf("  --max-threads=n          Set maximum thread number per cluster, default is 4\n");
 #endif
 #endif
 #if WASM_ENABLE_DEBUG_INTERP != 0
 #if WASM_ENABLE_DEBUG_INTERP != 0
-    printf("  -g=ip:port             Set the debug sever address, default is debug disabled\n");
-    printf("                           if port is 0, then a random port will be used\n");
+    printf("  -g=ip:port               Set the debug sever address, default is debug disabled\n");
+    printf("                             if port is 0, then a random port will be used\n");
 #endif
 #endif
-    printf("  --version              Show version information\n");
+    printf("  --version                Show version information\n");
     return 1;
     return 1;
 }
 }
 /* clang-format on */
 /* clang-format on */
@@ -320,6 +325,8 @@ main(int argc, char *argv[])
     uint32 env_list_size = 0;
     uint32 env_list_size = 0;
     const char *addr_pool[8] = { NULL };
     const char *addr_pool[8] = { NULL };
     uint32 addr_pool_size = 0;
     uint32 addr_pool_size = 0;
+    const char *ns_lookup_pool[8] = { NULL };
+    uint32 ns_lookup_pool_size = 0;
 #endif
 #endif
 #if BH_HAS_DLFCN
 #if BH_HAS_DLFCN
     const char *native_lib_list[8] = { NULL };
     const char *native_lib_list[8] = { NULL };
@@ -420,6 +427,18 @@ main(int argc, char *argv[])
                 token = strtok(NULL, ";");
                 token = strtok(NULL, ";");
             }
             }
         }
         }
+        else if (!strncmp(argv[0], "--allow-resolve=", 16)) {
+            if (argv[0][16] == '\0')
+                return print_help();
+            if (ns_lookup_pool_size
+                >= sizeof(ns_lookup_pool) / sizeof(ns_lookup_pool[0])) {
+                printf(
+                    "Only allow max ns lookup number %d\n",
+                    (int)(sizeof(ns_lookup_pool) / sizeof(ns_lookup_pool[0])));
+                return 1;
+            }
+            ns_lookup_pool[ns_lookup_pool_size++] = argv[0] + 16;
+        }
 #endif /* WASM_ENABLE_LIBC_WASI */
 #endif /* WASM_ENABLE_LIBC_WASI */
 #if BH_HAS_DLFCN
 #if BH_HAS_DLFCN
         else if (!strncmp(argv[0], "--native-lib=", 13)) {
         else if (!strncmp(argv[0], "--native-lib=", 13)) {
@@ -560,6 +579,8 @@ main(int argc, char *argv[])
                                env_list, env_list_size, argv, argc);
                                env_list, env_list_size, argv, argc);
 
 
     wasm_runtime_set_wasi_addr_pool(wasm_module, addr_pool, addr_pool_size);
     wasm_runtime_set_wasi_addr_pool(wasm_module, addr_pool, addr_pool_size);
+    wasm_runtime_set_wasi_ns_lookup_pool(wasm_module, ns_lookup_pool,
+                                         ns_lookup_pool_size);
 #endif
 #endif
 
 
     /* instantiate the module */
     /* instantiate the module */