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

Implement Berkeley Socket API for Intel SGX (#1061)

Implement Berkeley Socket API for Intel SGX
- bring Berkeley socket API in Intel SGX enclaves,
- adapt the documentation of the socket API to mention Intel SGX enclaves,
- adapt _iwasm_ in the mini-product _linux-sgx_ to support the same option as the one for _linux_,
- tested on the socket sample as provided by WAMR (the TCP client/server).
Jämes Ménétrey 3 лет назад
Родитель
Сommit
106974d915

+ 347 - 22
core/shared/platform/linux-sgx/sgx_socket.c

@@ -9,21 +9,194 @@
 
 #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
 
+/** OCALLs prototypes **/
 int
-ocall_socket(int *p_ret, int domain, int type, int protocol);
+ocall_accept(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
+             uint32_t addr_size);
+
+int
+ocall_bind(int *p_ret, int sockfd, const void *addr, uint32_t addrlen);
+
+int
+ocall_close(int *p_ret, int fd);
+
+int
+ocall_connect(int *p_ret, int sockfd, void *addr, uint32_t addrlen);
+
+int
+ocall_fcntl_long(int *p_ret, int fd, int cmd, long arg);
+
+int
+ocall_getsockname(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
+                  uint32_t addr_size);
+
 int
 ocall_getsockopt(int *p_ret, int sockfd, int level, int optname, void *val_buf,
                  unsigned int val_buf_size, void *len_buf);
 
 int
-ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
-              unsigned int msg_buf_size, int flags);
+ocall_listen(int *p_ret, int sockfd, int backlog);
+
+int
+ocall_recv(int *p_ret, int sockfd, void *buf, size_t len, int flags);
+
 int
 ocall_recvmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
               unsigned int msg_buf_size, int flags);
+
+int
+ocall_send(int *p_ret, int sockfd, const void *buf, size_t len, int flags);
+
+int
+ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
+              unsigned int msg_buf_size, int flags);
+
+int
+ocall_setsockopt(int *p_ret, int sockfd, int level, int optname, void *optval,
+                 unsigned int optlen);
+
 int
 ocall_shutdown(int *p_ret, int sockfd, int how);
 
+int
+ocall_socket(int *p_ret, int domain, int type, int protocol);
+/** OCALLs prototypes end **/
+
+/** In-enclave implementation of POSIX functions **/
+static bool
+is_little_endian()
+{
+    long i = 0x01020304;
+    unsigned char *c = (unsigned char *)&i;
+    return (*c == 0x04) ? true : false;
+}
+
+static void
+swap32(uint8 *pData)
+{
+    uint8 value = *pData;
+    *pData = *(pData + 3);
+    *(pData + 3) = value;
+
+    value = *(pData + 1);
+    *(pData + 1) = *(pData + 2);
+    *(pData + 2) = value;
+}
+
+static void
+swap16(uint8 *pData)
+{
+    uint8 value = *pData;
+    *(pData) = *(pData + 1);
+    *(pData + 1) = value;
+}
+
+static uint32
+htonl(uint32 value)
+{
+    uint32 ret;
+    if (is_little_endian()) {
+        ret = value;
+        swap32((uint8 *)&ret);
+        return ret;
+    }
+
+    return value;
+}
+
+static uint32
+ntohl(uint32 value)
+{
+    return htonl(value);
+}
+
+static uint16
+htons(uint16 value)
+{
+    uint16 ret;
+    if (is_little_endian()) {
+        ret = value;
+        swap16((uint8 *)&ret);
+        return ret;
+    }
+
+    return value;
+}
+
+static uint16
+ntohs(uint16 value)
+{
+    return htons(value);
+}
+
+/* Coming from musl, under MIT license */
+static int
+__inet_aton(const char *s0, struct in_addr *dest)
+{
+    const char *s = s0;
+    unsigned char *d = (void *)dest;
+    unsigned long a[4] = { 0 };
+    char *z;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        a[i] = strtoul(s, &z, 0);
+        if (z == s || (*z && *z != '.') || !isdigit(*s))
+            return 0;
+        if (!*z)
+            break;
+        s = z + 1;
+    }
+    if (i == 4)
+        return 0;
+    switch (i) {
+        case 0:
+            a[1] = a[0] & 0xffffff;
+            a[0] >>= 24;
+        case 1:
+            a[2] = a[1] & 0xffff;
+            a[1] >>= 16;
+        case 2:
+            a[3] = a[2] & 0xff;
+            a[2] >>= 8;
+    }
+    for (i = 0; i < 4; i++) {
+        if (a[i] > 255)
+            return 0;
+        d[i] = a[i];
+    }
+    return 1;
+}
+
+/* Coming from musl, under MIT license */
+static int
+inet_addr(const char *p)
+{
+    struct in_addr a;
+    if (!__inet_aton(p, &a))
+        return -1;
+    return a.s_addr;
+}
+
+static int
+inet_network(const char *p)
+{
+    return ntohl(inet_addr(p));
+}
+/** In-enclave implementation of POSIX functions end **/
+
+static int
+textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr_in *out)
+{
+    assert(textual);
+
+    out->sin_family = AF_INET;
+    out->sin_port = htons(port);
+    out->sin_addr.s_addr = inet_addr(textual);
+
+    return BHT_OK;
+}
+
 int
 socket(int domain, int type, int protocol)
 {
@@ -232,67 +405,219 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
                  unsigned int *addrlen)
 
 {
-    errno = ENOSYS;
-    return -1;
+    struct sockaddr addr_tmp;
+    unsigned int len = sizeof(struct sockaddr);
+
+    if (ocall_accept(sock, server_sock, &addr_tmp, &len, len) != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (*sock < 0) {
+        errno = get_errno();
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
 }
 int
 os_socket_bind(bh_socket_t socket, const char *host, int *port)
 {
-    errno = ENOSYS;
-    return -1;
+    struct sockaddr_in addr;
+    struct linger ling;
+    unsigned int socklen;
+    int ret;
+
+    assert(host);
+    assert(port);
+
+    ling.l_onoff = 1;
+    ling.l_linger = 0;
+
+    if (ocall_fcntl_long(&ret, socket, F_SETFD, FD_CLOEXEC) != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret < 0) {
+        goto fail;
+    }
+
+    if (ocall_setsockopt(&ret, socket, SOL_SOCKET, SO_LINGER, &ling,
+                         sizeof(ling))
+        != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret < 0) {
+        goto fail;
+    }
+
+    addr.sin_addr.s_addr = inet_addr(host);
+    addr.sin_port = htons(*port);
+    addr.sin_family = AF_INET;
+
+    if (ocall_bind(&ret, socket, &addr, sizeof(addr)) != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret < 0) {
+        goto fail;
+    }
+
+    socklen = sizeof(addr);
+
+    if (ocall_getsockname(&ret, socket, (void *)&addr, &socklen, socklen)
+        != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret == -1) {
+        goto fail;
+    }
+
+    *port = ntohs(addr.sin_port);
+
+    return BHT_OK;
+
+fail:
+    errno = get_errno();
+    return BHT_ERROR;
 }
 
 int
 os_socket_close(bh_socket_t socket)
 {
-    errno = ENOSYS;
-    return -1;
+    int ret;
+
+    if (ocall_close(&ret, socket) != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret == -1)
+        errno = get_errno();
+
+    return ret;
 }
 
 int
 os_socket_connect(bh_socket_t socket, const char *addr, int port)
-{}
+{
+    struct sockaddr_in addr_in = { 0 };
+    socklen_t addr_len = sizeof(struct sockaddr_in);
+    int ret = 0;
+
+    if ((ret = textual_addr_to_sockaddr(addr, port, &addr_in)) < 0) {
+        return ret;
+    }
+
+    if (ocall_connect(&ret, socket, &addr_in, addr_len) != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret == -1)
+        errno = get_errno();
+
+    return ret;
+}
 
 int
 os_socket_create(bh_socket_t *sock, int tcp_or_udp)
 {
-    errno = ENOSYS;
-    return -1;
+    if (!sock) {
+        return BHT_ERROR;
+    }
+
+    if (1 == tcp_or_udp) {
+        if (ocall_socket(sock, AF_INET, SOCK_STREAM, IPPROTO_TCP)
+            != SGX_SUCCESS) {
+            TRACE_OCALL_FAIL();
+            return -1;
+        }
+    }
+    else if (0 == tcp_or_udp) {
+        if (ocall_socket(sock, AF_INET, SOCK_DGRAM, 0) != SGX_SUCCESS) {
+            TRACE_OCALL_FAIL();
+            return -1;
+        }
+    }
+
+    if (*sock == -1) {
+        errno = get_errno();
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
 }
 
 int
 os_socket_inet_network(const char *cp, uint32 *out)
 {
-    errno = ENOSYS;
-    return -1;
+    if (!cp)
+        return BHT_ERROR;
+
+    *out = inet_network(cp);
+
+    return BHT_OK;
 }
 
 int
 os_socket_listen(bh_socket_t socket, int max_client)
 {
-    errno = ENOSYS;
-    return -1;
+    int ret;
+
+    if (ocall_listen(&ret, socket, max_client) != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return -1;
+    }
+
+    if (ret == -1)
+        errno = get_errno();
+
+    return ret;
 }
 
 int
 os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
 {
-    errno = ENOSYS;
-    return -1;
+    int ret;
+
+    if (ocall_recv(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    if (ret == -1)
+        errno = get_errno();
+
+    return ret;
 }
 
 int
 os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
 {
-    errno = ENOSYS;
-    return -1;
+    int ret;
+
+    if (ocall_send(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    if (ret == -1)
+        errno = get_errno();
+
+    return ret;
 }
 
 int
 os_socket_shutdown(bh_socket_t socket)
 {
-    errno = ENOSYS;
-    return -1;
+    return shutdown(socket, O_RDWR);
 }
 
 #endif

+ 43 - 2
core/shared/platform/linux-sgx/sgx_socket.h

@@ -14,11 +14,12 @@ extern "C" {
 
 #define SOL_SOCKET 1
 
+#define SO_TYPE 3
+#define SO_LINGER 13
+
 #define SOCK_STREAM 1
 #define SOCK_DGRAM 2
 
-#define SO_TYPE 3
-
 #define MSG_OOB 0x0001
 #define MSG_PEEK 0x0002
 #define MSG_DONTROUTE 0x0004
@@ -44,6 +45,16 @@ extern "C" {
 #define SHUT_WR 1
 #define SHUT_RDWR 2
 
+/* Address families.  */
+#define AF_INET 2 /* IP protocol family.  */
+
+/* Standard well-defined IP protocols.  */
+#define IPPROTO_TCP 6 /* Transmission Control Protocol.  */
+
+/* Types of sockets.  */
+#define SOCK_DGRAM \
+    2 /* Connectionless, unreliable datagrams of fixed maximum length.  */
+
 struct msghdr {
     void *msg_name;
     socklen_t msg_namelen;
@@ -54,6 +65,36 @@ struct msghdr {
     int msg_flags;
 };
 
+/* Internet address.  */
+struct in_addr {
+    uint32_t s_addr;
+};
+typedef struct in_addr in_addr_t;
+
+/* Structure describing an Internet socket address.  */
+#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr)	*/
+struct sockaddr_in {
+    uint16_t sin_family;
+    uint16_t sin_port;       /* Port number.  */
+    struct in_addr sin_addr; /* Internet address.  */
+
+    /* Pad to size of `struct sockaddr'. */
+    unsigned char__pad[__SOCK_SIZE__ - sizeof(uint16_t) - sizeof(uint16_t)
+                       - sizeof(struct in_addr)];
+};
+
+/* Structure used to manipulate the SO_LINGER option.  */
+struct linger {
+    int l_onoff;  /* Nonzero to linger on close.  */
+    int l_linger; /* Time to linger.  */
+};
+
+/* Structure describing a generic socket address.  */
+struct sockaddr {
+    unsigned short int sa_family; /* Common data: address family and length.  */
+    char sa_data[14];             /* Address data.  */
+};
+
 int
 socket(int domain, int type, int protocol);
 

+ 20 - 5
core/shared/platform/linux-sgx/sgx_wamr.edl

@@ -118,19 +118,34 @@ enclave {
         int ocall_pthread_rwlock_unlock([user_check]void *rwlock);
 
         int ocall_get_errno();
-        int ocall_socket(int domain, int type, int protocol);
+
+        /* sockets */
+        int ocall_accept(int sockfd, [in, size=addr_size]void *addr,
+                  [in, size=4] uint32_t *addrlen, uint32_t addr_size);
+        int ocall_bind(int sockfd, [in, size=addrlen]const void *addr,
+                 uint32_t addrlen);
+        int ocall_connect(int sockfd, [in, size=addrlen]void *addr, uint32_t addrlen);
+        int ocall_getsockname(int sockfd, [in, size=addr_size]void *addr,
+                              [in, out, size=4]uint32_t *addrlen, uint32_t addr_size);
         int ocall_getsockopt(int sockfd, int level, int optname,
                              [out, size=val_buf_size]void *val_buf,
                              unsigned int val_buf_size,
                              [in, out, size=4]void *len_buf);
-        ssize_t ocall_sendmsg(int sockfd,
-                              [in, size=msg_buf_size]void *msg_buf,
-                              unsigned int msg_buf_size,
-                              int flags);
+        int ocall_listen(int sockfd, int backlog);
+        int ocall_recv(int sockfd, [out, size=len]void *buf, size_t len, int flags);
         ssize_t ocall_recvmsg(int sockfd,
                               [in, out, size=msg_buf_size]void *msg_buf,
                               unsigned int msg_buf_size,
                               int flags);
+        int ocall_send(int sockfd, [in, size=len]const void *buf, size_t len, int flags);
+        ssize_t ocall_sendmsg(int sockfd,
+                              [in, size=msg_buf_size]void *msg_buf,
+                              unsigned int msg_buf_size,
+                              int flags);
+        int ocall_setsockopt(int sockfd, int level, int optname,
+                             [in, size=optlen]void *optval,
+                             unsigned int optlen);
         int ocall_shutdown(int sockfd, int how);
+        int ocall_socket(int domain, int type, int protocol);
     };
 };

+ 51 - 0
core/shared/platform/linux-sgx/untrusted/socket.c

@@ -6,6 +6,8 @@
 #include <sys/socket.h>
 #include <stdint.h>
 #include <stddef.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 int
 ocall_socket(int domain, int type, int protocol)
@@ -72,4 +74,53 @@ int
 ocall_shutdown(int sockfd, int how)
 {
     return shutdown(sockfd, how);
+}
+
+int
+ocall_setsockopt(int sockfd, int level, int optname, void *optval,
+                 unsigned int optlen)
+{
+    return setsockopt(sockfd, level, optname, optval, optlen);
+}
+
+int
+ocall_bind(int sockfd, const void *addr, uint32_t addrlen)
+{
+    return bind(sockfd, (const struct sockaddr *)addr, addrlen);
+}
+
+int
+ocall_getsockname(int sockfd, void *addr, uint32_t *addrlen, uint32_t addr_size)
+{
+    return getsockname(sockfd, (struct sockaddr *)addr, addrlen);
+}
+
+int
+ocall_listen(int sockfd, int backlog)
+{
+    return listen(sockfd, backlog);
+}
+
+int
+ocall_accept(int sockfd, void *addr, uint32_t *addrlen, uint32_t addr_size)
+{
+    return accept(sockfd, (struct sockaddr *)addr, addrlen);
+}
+
+int
+ocall_recv(int sockfd, void *buf, size_t len, int flags)
+{
+    return recv(sockfd, buf, len, flags);
+}
+
+int
+ocall_send(int sockfd, const void *buf, size_t len, int flags)
+{
+    return send(sockfd, buf, len, flags);
+}
+
+int
+ocall_connect(int sockfd, void *addr, uint32_t addrlen)
+{
+    return connect(sockfd, (const struct sockaddr *)addr, addrlen);
 }

+ 18 - 3
doc/socket_api.md

@@ -10,7 +10,7 @@ and `socket()`. Users can call those functions in WebAssembly code directly.
 Those WebAssembly socket calls will be dispatched to the imported
 functions and eventually will be implemented by host socket APIs.
 
-This document introduces a way to support _Berkeley/Posix Socket APIs_ in
+This document introduces a way to support the _Berkeley/POSIX Socket API_ in
 WebAssembly code.
 
 ## Patch the native code
@@ -24,7 +24,7 @@ native source code.
 #endif
 ```
 
-`__wasi__` is a Marco defined by WASI. The host compiler will not enable it.
+`__wasi__` is a macro defined by WASI. The host compiler will not enable it.
 
 ## CMake files
 
@@ -57,10 +57,25 @@ The _iwasm_ should be compiled with `WAMR_BUILD_LIBC_WASI=1`. By default, it is
 enabled.
 
 _iwasm_ accepts address ranges via an option, `--addr-pool`, to implement
-the capability control. All IP address the WebAssebmly application may need to `bind()` or `connect()` should be announced first. Every IP address should be in CIRD notation.
+the capability control. All IP address the WebAssembly application may need to `bind()` or `connect()`
+should be announced first. Every IP address should be in CIRD notation.
 
 ```bash
 $ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
 ```
 
 Refer to [socket api sample](../samples/socket-api) for more details.
+
+## Intel SGX support
+
+WAMR also supports the socket API within Intel SGX enclaves.
+
+The _iwasm_ should be compiled with `WAMR_BUILD_LIBC_WASI=1` and `WAMR_BUILD_LIB_PTHREAD=1`, which are enabled by default.
+
+Similarly to running _iwasm_ outside of an enclave, the allowed address ranges are given via the option `--addr-pool`.
+
+```bash
+$ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
+```
+
+Refer to [socket api sample](../samples/socket-api) for the compilation of the Wasm applications and [_iwasm_ for Intel SGX](../product-mini/platforms/linux-sgx) for the Wasm runtime.

+ 37 - 5
product-mini/platforms/linux-sgx/enclave-sample/App/App.cpp

@@ -227,6 +227,10 @@ print_help()
     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=           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("  --max-threads=n        Set maximum thread number per cluster, default is 4\n");
     return 1;
 }
@@ -550,9 +554,10 @@ app_instance_func(void *wasm_module_inst, const char *func_name, int app_argc,
 static bool
 set_wasi_args(void *wasm_module, const char **dir_list, uint32_t dir_list_size,
               const char **env_list, uint32_t env_list_size, int stdinfd,
-              int stdoutfd, int stderrfd, char **argv, uint32_t argc)
+              int stdoutfd, int stderrfd, char **argv, uint32_t argc,
+              const char **addr_pool, uint32_t addr_pool_size)
 {
-    uint64_t ecall_args[10];
+    uint64_t ecall_args[12];
 
     ecall_args[0] = (uint64_t)(uintptr_t)wasm_module;
     ecall_args[1] = (uint64_t)(uintptr_t)dir_list;
@@ -564,9 +569,11 @@ set_wasi_args(void *wasm_module, const char **dir_list, uint32_t dir_list_size,
     ecall_args[7] = stderrfd;
     ecall_args[8] = (uint64_t)(uintptr_t)argv;
     ecall_args[9] = argc;
+    ecall_args[10] = (uint64_t)(uintptr_t)addr_pool;
+    ecall_args[11] = addr_pool_size;
     if (SGX_SUCCESS
         != ecall_handle_command(g_eid, CMD_SET_WASI_ARGS, (uint8_t *)ecall_args,
-                                sizeof(uint64_t) * 10)) {
+                                sizeof(uint64_t) * 12)) {
         printf("Call ecall_handle_command() failed.\n");
     }
 
@@ -590,6 +597,8 @@ main(int argc, char *argv[])
     uint32_t dir_list_size = 0;
     const char *env_list[8] = { NULL };
     uint32_t env_list_size = 0;
+    const char *addr_pool[8] = { NULL };
+    uint32_t addr_pool_size = 0;
     uint32_t max_thread_num = 4;
 
     if (enclave_init(&g_eid) < 0) {
@@ -666,6 +675,26 @@ main(int argc, char *argv[])
                 return print_help();
             }
         }
+        /* TODO: parse the configuration file via --addr-pool-file */
+        else if (!strncmp(argv[0], "--addr-pool=", strlen("--addr-pool="))) {
+            /* like: --addr-pool=100.200.244.255/30 */
+            char *token = NULL;
+
+            if ('\0' == argv[0][12])
+                return print_help();
+
+            token = strtok(argv[0] + strlen("--addr-pool="), ",");
+            while (token) {
+                if (addr_pool_size >= sizeof(addr_pool) / sizeof(char *)) {
+                    printf("Only allow max address number %d\n",
+                           (int)(sizeof(addr_pool) / sizeof(char *)));
+                    return -1;
+                }
+
+                addr_pool[addr_pool_size++] = token;
+                token = strtok(NULL, ";");
+            }
+        }
         else if (!strncmp(argv[0], "--max-threads=", 14)) {
             if (argv[0][14] == '\0')
                 return print_help();
@@ -705,7 +734,8 @@ main(int argc, char *argv[])
 
     /* Set wasi arguments */
     if (!set_wasi_args(wasm_module, dir_list, dir_list_size, env_list,
-                       env_list_size, 0, 1, 2, argv, argc)) {
+                       env_list_size, 0, 1, 2, argv, argc, addr_pool,
+                       addr_pool_size)) {
         printf("%s\n", "set wasi arguments failed.\n");
         goto fail3;
     }
@@ -771,6 +801,8 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args)
     uint32_t dir_list_size = 0;
     const char *env_list[8] = { NULL };
     uint32_t env_list_size = 0;
+    const char *addr_pool[8] = { NULL };
+    uint32_t addr_pool_size = 0;
     uint32_t max_thread_num = 4;
     char *wasm_files[16];
     void *wasm_module_inst[16];
@@ -845,7 +877,7 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args)
         /* Set wasi arguments */
         if (!set_wasi_args(wasm_module, dir_list, dir_list_size, env_list,
                            env_list_size, stdinfd, stdoutfd, stderrfd, argv,
-                           argc)) {
+                           argc, addr_pool, addr_pool_size)) {
             printf("%s\n", "set wasi arguments failed.\n");
             unload_module(wasm_module);
             free(wasm_file_buf);

+ 27 - 1
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp

@@ -50,6 +50,8 @@ typedef struct EnclaveModule {
     uint32 wasi_dir_list_size;
     char **wasi_env_list;
     uint32 wasi_env_list_size;
+    char **wasi_addr_pool_list;
+    uint32 wasi_addr_pool_list_size;
     char **wasi_argv;
     uint32 wasi_argc;
     bool is_xip_file;
@@ -407,6 +409,8 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
     char **wasi_argv = *(char ***)args++;
     char *p, *p1;
     uint32 wasi_argc = *(uint32 *)args++;
+    char **addr_pool_list = *(char ***)args++;
+    uint32 addr_pool_list_size = *(uint32 *)args++;
     uint64 total_size = 0;
     int32 i, str_len;
 
@@ -414,6 +418,7 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
 
     total_size += sizeof(char *) * (uint64)dir_list_size
                   + sizeof(char *) * (uint64)env_list_size
+                  + sizeof(char *) * (uint64)addr_pool_list_size
                   + sizeof(char *) * (uint64)wasi_argc;
 
     for (i = 0; i < dir_list_size; i++) {
@@ -424,6 +429,10 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
         total_size += strlen(env_list[i]) + 1;
     }
 
+    for (i = 0; i < addr_pool_list_size; i++) {
+        total_size += strlen(addr_pool_list[i]) + 1;
+    }
+
     for (i = 0; i < wasi_argc; i++) {
         total_size += strlen(wasi_argv[i]) + 1;
     }
@@ -436,7 +445,7 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
     }
 
     p1 = p + sizeof(char *) * dir_list_size + sizeof(char *) * env_list_size
-         + sizeof(char *) * wasi_argc;
+         + sizeof(char *) * addr_pool_list_size + sizeof(char *) * wasi_argc;
 
     if (dir_list_size > 0) {
         enclave_module->wasi_dir_list = (char **)p;
@@ -462,6 +471,18 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
         p += sizeof(char *) * env_list_size;
     }
 
+    if (addr_pool_list_size > 0) {
+        enclave_module->wasi_addr_pool_list = (char **)p;
+        enclave_module->wasi_addr_pool_list_size = addr_pool_list_size;
+        for (i = 0; i < addr_pool_list_size; i++) {
+            enclave_module->wasi_addr_pool_list[i] = p1;
+            str_len = strlen(addr_pool_list[i]);
+            bh_memcpy_s(p1, str_len + 1, addr_pool_list[i], str_len + 1);
+            p1 += str_len + 1;
+        }
+        p += sizeof(char *) * addr_pool_list_size;
+    }
+
     if (wasi_argc > 0) {
         enclave_module->wasi_argv = (char **)p;
         enclave_module->wasi_argc = wasi_argc;
@@ -481,6 +502,11 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
         (stdinfd != -1) ? stdinfd : 0, (stdoutfd != -1) ? stdoutfd : 1,
         (stderrfd != -1) ? stderrfd : 2);
 
+    wasm_runtime_set_wasi_addr_pool(
+        enclave_module->module,
+        (const char **)enclave_module->wasi_addr_pool_list,
+        addr_pool_list_size);
+
     *args_org = true;
 }
 #else