Skip to content

wasip3: sockets-tcp-listen::test_inherited_properties — accepted socket's get-send-buffer-size differs from listener (Linux tcp_wmem autotune) #13397

@cataggar

Description

@cataggar

Summary

The upstream wasi-testsuite fixture wasm32-wasip3/sockets-tcp-listen (tests/rust/wasm32-wasip3/src/bin/sockets-tcp-listen.rs's test_inherited_properties) panics on wasmtime 44.0.1 (first stable release with -Sp3 support). The fixture binds a TCP listener, accepts an inbound connection, and asserts that every reachable socket option on the accepted socket equals the same option on the listening socket. wasmtime's get_send_buffer_size for the accepted socket reports a different value from the listener — Ok(1313280) vs Ok(8192) — and assert_eq! panics.

Reproduction

cd tests/rust/wasm32-wasip3 && make build && cd -
wasmtime -Wcomponent-model-async -Sp3,inherit-network \
    tests/rust/testsuite/wasm32-wasip3/sockets-tcp-listen.wasm

Output (trimmed):

thread '<unnamed>' (1) panicked at src/bin/sockets-tcp-listen.rs:53:13:
assertion `left == right` failed
  left: Ok(1313280)
 right: Ok(8192)
…
   13:   0x3703 - sockets_tcp_listen…!sockets_tcp_listen…::test_inherited_properties::{closure#0}::{closure#0}
…
    1: wasm trap: wasm `unreachable` instruction executed

The asserting code (tests/wasi-testsuite tests/rust/wasm32-wasip3/src/bin/sockets-tcp-listen.rs:36-58):

let mut accept = sock.listen().unwrap();
futures::join!(
    async {
        let next = accept.next().await.unwrap();
        assert_eq!(next.get_address_family(), sock.get_address_family());
        assert_eq!(next.get_keep_alive_enabled(), sock.get_keep_alive_enabled());
        assert_eq!(next.get_keep_alive_idle_time(), sock.get_keep_alive_idle_time());
        assert_eq!(next.get_keep_alive_interval(), sock.get_keep_alive_interval());
        assert_eq!(next.get_keep_alive_count(), sock.get_keep_alive_count());
        assert_eq!(next.get_hop_limit(), sock.get_hop_limit());
        assert_eq!(next.get_receive_buffer_size(), sock.get_receive_buffer_size());
        assert_eq!(next.get_send_buffer_size(), sock.get_send_buffer_size());  // ← panics here
    },
    async { client.connect(local_addr).await.unwrap(); }
);

Cross-runtime parity

The same fixture passes on the WAMR-Zig WASIp3 host (40 / 40 wasm32-wasip3 fixtures pass, this one included). The WAMR host caches the user-set buffer size on the listening socket rep and propagates that exact value into the accepted socket's rep, regardless of what the Linux kernel may have autotuned SO_SNDBUF to behind its back (which is the source of the 1313280 value wasmtime reports — Linux applies tcp_wmem autotuning on accepted sockets independently of the listener's stored value).

If the WIT contract for tcp-socket.[get/set]-send-buffer-size is "the host caches the last value the guest set and returns it unchanged on get", wasmtime 44 needs to do the same caching. If the contract allows the kernel to silently override the stored value (a reasonable interpretation since SO_SNDBUF is autotuned by Linux), then the fixture's assert_eq! is too strict and should be relaxed (or dropped) for the buffer-size pair. Either way it's a wasmtime-side delta from the only other WASIp3 runtime that's currently passing the full corpus.

Why this matters

Same as #11342 — this is one of four wasm32-wasip3 fixtures that fail on stock wasmtime 44.0.1 but pass on the WAMR-Zig host; tracked in cataggar/wamr#583 C1.

Environment

  • wasmtime 44.0.1 (f302ebd6b 2026-04-30)
  • wasi-testsuite 40c1f7d tests/rust/testsuite/wasm32-wasip3/sockets-tcp-listen.wasm
  • Linux 6.x aarch64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions