Skip to content

setDatatype writes host-endian integers to Wasm memory on big-endian (s390x) #552

Description

@vinayakray19

Summary

WasmBase::setDatatype in include/proxy-wasm/wasm.h writes primitive values to Wasm linear memory using raw setMemory without endian conversion. Wasm memory is always little-endian, but on big-endian hosts (e.g. s390x) the host writes native big-endian bytes.

This affects hostcalls that return integers via output pointers, including proxy_get_log_level (exports::get_log_level in src/exports.cc).

Impact

On s390x, Rust Wasm plugins calling proxy_get_log_level during proxy_on_configure can fail with:

Function: proxy_on_configure failed: Uncaught RuntimeError: memory access out of bounds

Similar failures were reported previously in #197; PR #198 fixed several endianness paths but setDatatype was not updated.

Root cause

setWord correctly uses htowasm before writing to Wasm memory:

uint32_t word32 = htowasm(word.u32(), true);
memcpy(memory_->data() + pointer, &word32, size);

setDatatype does not:

return wasm_vm_->setMemory(ptr, sizeof(T), &t);

setDatatype is used in many exports (get_log_level, get_metric, define_metric, get_current_time_nanoseconds, etc.).

Proposed fix

Convert to Wasm byte order before writing:

template <typename T> inline bool WasmBase::setDatatype(uint64_t ptr, const T &t) {
  T value = htowasm(t, wasm_vm_->usesWasmByteOrder());
  return wasm_vm_->setMemory(ptr, sizeof(T), &value);
}

Do not fix this in setMemory itself — that API is also used for opaque byte blobs (strings, random data, WASI structs).

Test plan

  • Add regression test asserting setDatatype stores little-endian bytes in Wasm memory
  • Verify on s390x CI (Wasmtime matrix job)

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