Stream: wamr

Topic: wasi_args propagation to linked module


view this post on Zulip Boris Kreminski (Jul 25 2025 at 19:13):

I've tried to call some socket api from within linked (dependency) module. I've followed the reactor/command pattern guide from here: https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/multi_module.md, and my linked module is pretty much based on addr_resolve.c from samples.

So, the command module has main() and calls resolve() function referenced from reactor module. I've used iwasm to run it: iwasm --allow-resolve=localhost --addr-pool=0.0.0.0/0 command.wasm (had to re-build it with WAMR_BUILD_MULTI_MODULE=1). I've supplied both --allow-resolve and --addr-pool switched, but was getting getaddrinfo: Permission denied error.
This behavior only happens whenever reactor module is linked. When reactor is instantiated directly and resolve() function is called, it works as expected.
Digging a bit deeper, I noticed that upon instantiation of a linked module, neither addr_pool nor ns_lookup_pool were not initialized.
Looking at wasm_runtime_set_wasi_args_ex function signature, I've noticed that it lacks addr_pool and ns_lookup_pool arguments (just like it has for map_dir_list and env_list for --dir and --env command-line arguments respectively). To debug it a bit further, I simply modified the wasm_runtime_set_wasi_args_ex signature to include both addr_pool and ns_lookup_pool, just to make a necessary assignment before a call to wasm_propagate_wasi_args:

    wasi_args->addr_pool = addr_pool;
    wasi_args->addr_count = addr_pool_size;
    wasi_args->ns_lookup_pool = ns_lookup_pool;
    wasi_args->ns_lookup_count = ns_lookup_pool_size;

That worked for me (a linked module instantiated successfully with properly propagated wasi_args), but I'm curious whether this looks like a missing part in current implementation, or some misconfiguration on my end? Is it by design? I am assuming that during the propagation, the linked module inherits all the permissions from main module, but please correct me if I am wrong.

Any feedback is appreciated, thank you! The super basic example code is below:

reactor.c:

/*
 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 */

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __wasi__
#include <wasi_socket_ext.h>
#else
#include <netdb.h>
#endif

int lookup_host(const char *host)
{
    struct addrinfo hints, *res, *result;
    int errcode;
    char addrstr[100];
    void *ptr;

    printf("lookup_host: enter %s\n", host);

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    printf("lookup_host: calling getaddrinfo\n");

    errcode = getaddrinfo(host, NULL, &hints, &result);
    if (errcode != 0)
    {
        perror("getaddrinfo");
        printf("getaddrinfo error %d", errcode);
        return -1;
    }

    printf("After getaddrinfo %s\n", host);

    res = result;

    printf("Host: %s\n", host);
    while (res)
    {
        switch (res->ai_family)
        {
        case AF_INET:
            ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
            break;
        case AF_INET6:
            ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
            break;
        default:
            printf("Unsupported address family: %d\n", res->ai_family);
            continue;
        }
        inet_ntop(res->ai_family, ptr, addrstr, 100);
        printf("IPv%d address: %s (%s)\n", res->ai_family == AF_INET6 ? 6 : 4,
               addrstr, res->ai_socktype == SOCK_STREAM ? "TCP" : "UDP");
        res = res->ai_next;
    }

    freeaddrinfo(result);

    return EXIT_SUCCESS;
}

__attribute__((export_name("resolve"))) int
resolve()
{
    printf("reactor: resolve enter\n");
    return lookup_host("localhost");
}

command.c:

#include <stdio.h>
#include <stdlib.h>

__attribute__((import_module("reactor")))
__attribute__((import_name("resolve"))) extern int
resolve();

int main(int argc, char *argv[])
{
    resolve();

    return 0;
}
WebAssembly Micro Runtime (WAMR). Contribute to bytecodealliance/wasm-micro-runtime development by creating an account on GitHub.

Last updated: Dec 06 2025 at 07:03 UTC