Skip to content

Pebble: static XS machine lands in kernel heap -> MPU fault when FFI hands user code direct pointers into XS storage #1647

Description

@jplexer

Build environment: macOS (also reproduces on Linux)

Moddable SDK version: Pebble fork based on 8.2.3 (git describe:
8.2.3-4-g25f1a3bb1), as vendored in PebbleOS third_party/moddable/moddable

Target device: Pebble watch (ARMv8-M, MPU-enforced privilege separation).
Reproduces both on real hardware and on the Pebble QEMU emulator

Description

On the Pebble port, the host-allocated XS machine for an app can be placed entirely in the kernel (privileged) heap. That is harmless for an ordinary machine, but FFI dispatch runs unprivileged and hands the generated mc.ffi.c raw pointers into XS storage (slots, string chunks, ArrayBuffer backing). When that storage lives in the kernel heap, the first unprivileged dereference hits privileged memory and the MPU faults, killing the app.

Non-FFI machines never notice because only the privileged runtime touches that storage. FFI breaks the assumption: dispatch runs unprivileged (mcu_call_unprivileged) and fxToStringHandle / fxToArrayBufferHandle / slot handles pass mc.ffi.c direct pointers into XS storage with no copy-out.

Steps to Reproduce

  1. Build PebbleOS from main
  2. Launch "helloffi" in the Pebble QEMU emulator
  3. See the Memory Management fault (logged below) and the app get killed.

Expected behavior

XS storage that is reachable by unprivileged user code (anything handed out through FFI handles) must not live in the privileged kernel heap, so the unprivileged FFI dispatcher can dereference it without faulting. FFI calls should return normally instead of MPU-faulting.

Fault captured over the QEMU console (minimized to the most important information):

[Memory Management Failure!] Task: App <JS - FFI>
CFSR 0x82 = MMARVALID | DACCVIOL
MMFAR 0x20032b34 <- faulting data address: inside the kernel heap (privileged)
PC 0x200516ae <- inside app RAM (region "Task Specific 1", UserRW):
the unprivileged generated mc.ffi.c dispatcher

Configured regions at fault time:
4 < Task Specific 1 >: Addr 0x2004f400 Size 0x00030800 Perms: PrivRW_UserRW
5 < Task Specific 2 >: Addr 0x2004c400 Size 0x00003000 Perms: PrivRW
Unprivileged code (PC in app RAM) dereferences a pointer into the kernel heap (0x20032b34, not covered by any unprivileged region) -> DACCVIOL.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions