Bug 585 - add bounds-checked load/store instructions for WebAssembly
Summary: add bounds-checked load/store instructions for WebAssembly
Status: CONFIRMED
Alias: None
Product: Libre-SOC's first SoC
Classification: Unclassified
Component: Specification (show other bugs)
Version: unspecified
Hardware: Other Linux
: --- enhancement
Assignee: Jacob Lifshay
URL:
Depends on:
Blocks: 584
  Show dependency treegraph
 
Reported: 2021-01-27 16:45 GMT by Jacob Lifshay
Modified: 2022-09-21 00:26 BST (History)
3 users (show)

See Also:
NLnet milestone: ---
total budget (EUR) for completion of task and all subtasks: 0
budget (EUR) for this task, excluding subtasks' budget: 0
parent task for budget allocation:
child tasks for budget allocation:
The table of payments (in EUR) for this task; TOML format:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jacob Lifshay 2021-01-27 16:45:17 GMT
http://lists.libre-soc.org/pipermail/libre-soc-dev/2021-January/001914.html

We would just need semantics like the following:
address = compute-address-like-normal()
if instruction-has-32-bit-address: # separate instruction bit
    address &= 0xFFFFFFFF
if address < 0 or address + load_store_size >= wasm-limit-spr: # 64-bit addition
    trap, causing SIGSEGV
address += wasm-base-address-spr # always a 64-bit addition
normal-load-store(address, data)

the wasm-limit-spr is aligned to 2^16 in the WebAssembly spec.
the wasm-base-address-spr is aligned to at least 16 bytes, probably to a whole 4kB page.


Having a separate instruction of the above that just does the address check/calculation and returns the computed address would also be handy for things like calling memcpy or for atomics or other ops where we don't have merged check-and-do-op instructions. For the separate calculate-wasm-address instruction, load_store_size is either a register or an immediate, it is often 1, 2, 4, 8, or 16.
Comment 1 Luke Kenneth Casson Leighton 2021-01-27 17:01:10 GMT
i wonder if fine-grained IOMMU would do the job well.
Comment 2 Jacob Lifshay 2021-01-27 17:02:27 GMT
fixed wraparound bug in semantics code.

64-bit wasm memory addresses are a proposed wasm extension:
https://github.com/WebAssembly/memory64

another proposed wasm extension is having multiple accessible wasm memories:
https://github.com/webassembly/multi-memory
this would mean having a small table of wasm-base-address-spr wasm-limit-spr pairs, instructions would have an immediate telling them which table entry to use.
Comment 3 Jacob Lifshay 2021-01-27 17:10:36 GMT
(In reply to Luke Kenneth Casson Leighton from comment #1)
> i wonder if fine-grained IOMMU would do the job well.

I don't think that's the right place to do the bounds checking, since it needs to happen before the MMU's page table lookup (IOMMU happens after MMU translation iirc) otherwise we have to allocate 4GB of memory space again (or have a separate bounds check beforehand for 64-bit wasm addresses) defeating the whole purpose of the additional support.

remember, wasm is designed to run potential-attacker code in-process with runtime bounds checks to prevent wasm from accessing memory outside of the assigned range.
Comment 4 Jacob Lifshay 2021-01-28 19:19:24 GMT
Mentioned on the WASM 64-bit memory proposal repo:
https://github.com/WebAssembly/memory64/issues/15
Comment 5 Jacob Lifshay 2021-01-29 00:42:39 GMT
Bounds-check semantics for 64-bit memory:
https://github.com/WebAssembly/memory64/issues/3
Comment 6 Jacob Lifshay 2022-09-11 14:28:35 BST
wasm ld/st ops could fit in the new WIP ld/st-shift encoding space:
https://bugs.libre-soc.org/show_bug.cgi?id=905#c9

a separate only-calculate-address op is still needed for memcpy, atomics, OS read/write, etc.