How d-e-e-p-t-h-i/softtee works
Purpose and Entry Points
PEX SofTEE is a Linux prototype for kernel-assisted, intra-process protected execution. A process creates a protected context, maps kernel-owned memory, and explicitly enters/exits it via /dev/pex ioctls. Primary entry points are the kernel module in kernel/pex_main.c, the user runtime in libpex/src/pex.c, and the public ABI in libpex/include/pex.h and libpex/include/pex_uapi.h.
Kernel Protection Authority
kernel/pex_main.c implements pex.ko, the authoritative isolation layer. It registers /dev/pex, owns protected-context lifecycle and memory mappings, and enforces access based on active context and thread ownership. Its ioctl control plane covers context creation, entry, exit, destruction, and state queries. It also exposes aggregate and per-context telemetry through /proc/pex_stats.
• kernel/pex_main.c
• kernel/Makefile
Context Lifecycle and Access Boundary
The core boundary is between ordinary process memory and a context’s protected mapping. User code allocates a context through the library, receives a mapping, calls enter before touching it, then exits and destroys it. Access outside an active context—or from a non-owner thread under PEX_POLICY_OWNER_THREAD_ONLY—faults through kernel mapping protections. This is software/kernel isolation, not hardware-backed TEE isolation.
• libpex/include/pex_uapi.h
• kernel/pex_main.c
• libpex/src/pex.c
User-Space Runtime Contract
libpex is the consumer-facing C API and translates runtime calls into device opens, ioctl operations, and mapping management. It is built as static and shared libraries, allowing examples, tests, and demos to share one ABI rather than duplicating device protocol logic.
• libpex/include/pex.h
• libpex/src/pex.c
• libpex/Makefile
Workloads, Validation, and Demonstration
Console workloads exercise the intended behavior: protected work while entered and fault-gated access while inactive or incorrectly threaded. The Tkinter viewer demonstrates a visible protected-reveal flow: it decrypts an asset at startup, copies plaintext into the protected mapping on entry, copies to a normal display buffer, then wipes buffers on exit. The display path is explicitly outside the protection boundary.
• examples/protected_workload.c
• examples/showcase_blocking.c
• demo/pex_viewer.py
Host Deployment Flow
The host workflow builds the library, module, and consumers from the top-level Makefile. Privileged setup loads/reloads pex.ko, creates /dev/pex, and assigns usable permissions; application execution then occurs as an ordinary user process against that device.
• Makefile
• scripts/dev_setup.sh
• scripts/run_all.sh
Reproducible Guest Integration
Buildroot packages the module and PEX artifacts into an AArch64 root filesystem for QEMU-based validation. The external package definition integrates PEX into the image; the rootfs init hook loads the module and invokes bundled validation scripts under /opt/pex. This provides a separate runtime environment from the host kernel/module workflow.
• buildroot/package/pex/pex.mk
• buildroot/overlay/etc/init.d/S99pex
• buildroot/build_image.sh
Main entry points: pex.c libpex runtime · pex_main.c pex.ko protection layer · pex.mk Buildroot PEX package · pex_uapi.h PEX UAPI
Components 17
Kernel authority
Authoritative protection and device boundary.
- Module build
kernel/Makefile - pex.ko protection layer · Owns contexts, mappings, access enforcement, and telemetry.
kernel/pex_main.c - /dev/pex ioctl plane · Context lifecycle, entry/exit, destruction, and state queries.
- /proc/pex_stats · Aggregate and per-context statistics.
kernel/pex_main.c
User runtime and workloads
Consumer ABI and protected execution clients.
- libpex public API · Consumer-facing protected-context contract.
libpex/include/pex.h - PEX UAPI · Shared ioctl and policy definitions.
libpex/include/pex_uapi.h - libpex runtime · Translates API calls into device ioctls and mapping management.
libpex/src/pex.c - libpex artifacts · Produces static and shared libraries.
libpex/Makefile - Console workloads · Exercise entered access and fault-gated inactive or wrong-thread access.
examples/protected_workload.c - Thread-policy demo · Demonstrates owner-thread-only access behavior.
examples/showcase_blocking.c - Protected reveal viewer · Copies plaintext through protected memory into an unprotected display buffer, then wipes it.
demo/pex_viewer.py
Host deployment
Build and privileged module setup.
- Top-level build · Builds module, library, and consumers.
Makefile - Privileged device setup · Loads the module and provisions /dev/pex.
scripts/dev_setup.sh - Host validation runner
scripts/run_all.sh
Buildroot guest integration
Separate AArch64/QEMU image workflow.
- Buildroot PEX package · Packages PEX artifacts into an AArch64 root filesystem.
buildroot/package/pex/pex.mk - Guest init hook · Loads pex.ko and runs bundled validation under /opt/pex.
buildroot/overlay/etc/init.d/S99pex - Guest image build · Builds the QEMU-oriented AArch64 image.
buildroot/build_image.sh
Connections 21
- Top-level build → Module build: builds
- Top-level build → libpex artifacts: builds
- Module build → pex.ko protection layer: produces
- Privileged device setup → pex.ko protection layer: loads/reloads
- Privileged device setup → /dev/pex ioctl plane: creates and permits
- pex.ko protection layer → /dev/pex ioctl plane: registers
- pex.ko protection layer → /proc/pex_stats: exports
- libpex public API → libpex runtime: implemented by
- PEX UAPI → libpex runtime: defines ABI for
- PEX UAPI → pex.ko protection layer: shared ioctl ABI
- libpex artifacts → libpex runtime: packages
- libpex runtime → /dev/pex ioctl plane: opens, ioctls, maps
- Console workloads → libpex runtime: uses
- Thread-policy demo → libpex runtime: uses
- Protected reveal viewer → libpex runtime: uses protected mapping
- Host validation runner → Console workloads: runs
- Buildroot PEX package → pex.ko protection layer: packages
- Buildroot PEX package → libpex runtime: packages
- Guest image build → Buildroot PEX package: integrates
- Guest image build → Guest init hook: installs overlay
- Guest init hook → pex.ko protection layer: loads in guest