Pārlūkot izejas kodu

Fix socket-api send/recv issue and c-api sample callback_chain issue (#1158)

Re-implement socket api send/recv in an atomic-like way, fix the return value
check in posix.c.
And fix wasm-c-api sample callback_chain calling malloc issue.
liang.he 3 gadi atpakaļ
vecāks
revīzija
3ba2d7e7de

+ 82 - 28
core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c

@@ -1185,10 +1185,19 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
     struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
     uint64 total_size;
     uint32 i;
+    iovec_app_t *ri_data_orig = ri_data;
+    uint8 *buf = NULL;
+    uint8 *buf_begin = NULL;
     wasi_errno_t err;
+    size_t recv_bytes = 0;
 
-    if (!wasi_ctx)
+    if (!wasi_ctx) {
         return __WASI_EINVAL;
+    }
+
+    if (ri_data_len == 0) {
+        return __WASI_EINVAL;
+    }
 
     total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
     if (!validate_native_addr(ro_data_len, (uint32)sizeof(uint32))
@@ -1197,27 +1206,49 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
         || !validate_native_addr(ri_data, (uint32)total_size))
         return __WASI_EINVAL;
 
-    /* recv ri_data one by one */
+    /* receive and scatter*/
+    for (i = 0; i < ri_data_len; i++, ri_data++) {
+        total_size += ri_data->buf_len;
+    }
+    if (total_size >= UINT32_MAX
+        || !(buf_begin = wasm_runtime_malloc((uint32)total_size))) {
+        return __WASI_ENOMEM;
+    }
+    memset(buf_begin, 0, total_size);
+
     *ro_data_len = 0;
+    err = wasmtime_ssp_sock_recv(curfds, sock, buf_begin, total_size,
+                                 &recv_bytes);
+    if (err != __WASI_ESUCCESS) {
+        goto fail;
+    }
+    *ro_data_len = (uint32)recv_bytes;
+
+    buf = buf_begin;
+    ri_data = ri_data_orig;
     for (i = 0; i < ri_data_len; ri_data++, i++) {
-        void *buf;
-        size_t bytes_recv;
+        char *native_addr;
 
-        if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) {
-            return __WASI_EINVAL;
+        if ((uint32)(buf - buf_begin) >= *ro_data_len) {
+            break;
         }
 
-        buf = (void *)addr_app_to_native(ri_data->buf_offset);
-        err = wasmtime_ssp_sock_recv(curfds, sock, buf, ri_data->buf_len,
-                                     &bytes_recv);
-        if (err != __WASI_ESUCCESS) {
-            return err;
+        if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) {
+            err = __WASI_EINVAL;
+            goto fail;
         }
-        *ro_data_len += bytes_recv;
+
+        native_addr = (void *)addr_app_to_native(ri_data->buf_offset);
+        bh_memcpy_s(native_addr, ri_data->buf_len, buf, ri_data->buf_len);
+        buf += ri_data->buf_len;
     }
 
     *ro_flags = ri_flags;
-    return __WASI_ESUCCESS;
+fail:
+    if (buf_begin) {
+        wasm_runtime_free(buf_begin);
+    }
+    return err;
 }
 
 static wasi_errno_t
@@ -1232,12 +1263,21 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
     wasm_module_inst_t module_inst = get_module_inst(exec_env);
     wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
     struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
-    uint64 total_size;
+    uint64 total_size = 0;
     uint32 i;
+    const iovec_app_t *si_data_orig = si_data;
+    uint8 *buf = NULL;
+    uint8 *buf_begin = NULL;
     wasi_errno_t err;
+    size_t send_bytes = 0;
 
-    if (!wasi_ctx)
+    if (!wasi_ctx) {
+        return __WASI_EINVAL;
+    }
+
+    if (si_data_len == 0) {
         return __WASI_EINVAL;
+    }
 
     total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
     if (!validate_native_addr(so_data_len, sizeof(uint32))
@@ -1245,26 +1285,40 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
         || !validate_native_addr((void *)si_data, (uint32)total_size))
         return __WASI_EINVAL;
 
-    /* send si_data one by one */
-    *so_data_len = 0;
+    /* gather and send */
     for (i = 0; i < si_data_len; i++, si_data++) {
-        void *buf;
-        size_t bytes_sent;
+        total_size += si_data->buf_len;
+    }
+    if (total_size >= UINT32_MAX
+        || !(buf_begin = wasm_runtime_malloc((uint32)total_size))) {
+        return __WASI_ENOMEM;
+    }
+
+    buf = buf_begin;
+    si_data = si_data_orig;
+    for (i = 0; i < si_data_len; i++, si_data++) {
+        char *native_addr;
 
         if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
-            return __WASI_EINVAL;
+            err = __WASI_EINVAL;
+            goto fail;
         }
 
-        buf = (void *)addr_app_to_native(si_data->buf_offset);
-        err = wasmtime_ssp_sock_send(curfds, sock, buf, si_data->buf_len,
-                                     &bytes_sent);
-        if (err != __WASI_ESUCCESS) {
-            return err;
-        }
-        *so_data_len += bytes_sent;
+        native_addr = (char *)addr_app_to_native(si_data->buf_offset);
+        bh_memcpy_s(buf, si_data->buf_len, native_addr, si_data->buf_len);
+        buf += si_data->buf_len;
     }
 
-    return __WASI_ESUCCESS;
+    *so_data_len = 0;
+    err = wasmtime_ssp_sock_send(curfds, sock, buf_begin, total_size,
+                                 &send_bytes);
+    *so_data_len = (uint32)send_bytes;
+
+fail:
+    if (buf_begin) {
+        wasm_runtime_free(buf_begin);
+    }
+    return err;
 }
 
 static wasi_errno_t

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

@@ -3041,7 +3041,7 @@ wasmtime_ssp_sock_recv(
 
     ret = os_socket_recv(fd_number(fo), buf, buf_len);
     fd_object_release(fo);
-    if (BHT_OK != ret) {
+    if (-1 == ret) {
         return convert_errno(errno);
     }
 
@@ -3067,7 +3067,7 @@ wasmtime_ssp_sock_send(
 
     ret = os_socket_send(fd_number(fo), buf, buf_len);
     fd_object_release(fo);
-    if (BHT_OK != ret) {
+    if (-1 == ret) {
         return convert_errno(errno);
     }
 

+ 11 - 1
samples/wasm-c-api/src/callback_chain.c

@@ -60,7 +60,17 @@ enum EXPORT_ITEM_NAME {
 
 DEFINE_FUNCTION(get_pairs)
 {
-    call_wasm_function(e_malloc, args, results, "malloc");
+    wasm_val_vec_t as = { 0 };
+    wasm_val_t data[1] = { WASM_I32_VAL(10) };
+    wasm_val_vec_new(&as, 1, data);
+    if (as.data == NULL) {
+        printf("ERROR: create parameters failed\n");
+        return NULL;
+    }
+
+    call_wasm_function(e_malloc, &as, results, "malloc");
+
+    wasm_val_vec_delete(&as);
     return NULL;
 }