Filesystem Hardening
Introduction
Torizon OS already separates immutable operating system content, held in /usr and managed by OSTree, from writable state in /var and the /etc merge layer. Hardening at the filesystem level is therefore about three things: the mount options on the writable areas, keeping applications inside that model, and enabling the integrity and encryption features that Toradex supports at image build time.
This article is part of the Production Hardening Checklist, which also explains how to persist these changes across a fleet.
This article complies with the Typographic Conventions for the Toradex Documentation.
Mount Options for /tmp
The /tmp directory is world-writable shared scratch space. Mounting it nosuid and nodev stops setuid binaries and device nodes placed there from becoming privilege-escalation tools. Adding noexec additionally blocks execution from /tmp, which some software uses as temporary scratch space for helper binaries. That can break those workloads, so noexec is not universally safe.
On Torizon OS, /tmp is already a tmpfs mounted nosuid,nodev, without noexec:
/tmp tmpfs rw,nosuid,nodev,...
That baseline is acceptable for production. Add noexec only after you have tested that your application, your update flow, and your tooling do not need to execute anything from /tmp.
The trade-offs are:
| Adding noexec to /tmp | Leaving the stock nosuid,nodev |
|---|---|
Blocks execution of binaries placed in /tmp | Matches stock Torizon OS, with fewer application breakages |
May break installers, scripts, and tools that unpack and execute helpers from /tmp | Leaves /tmp executable |
| Requires product-specific testing before you roll it out to a fleet | Still protects against setuid binaries and device nodes through the existing flags |
Treat noexec on /tmp as a consideration rather than a default requirement.
Mount Options for /var and /data
The /var directory holds Docker state, logs, and application data, which makes it the main writable surface on the device. Mounting it nosuid, nodev, and noexec reduces the usefulness of planting setuid binaries, device nodes, or executable payloads there.
Remount it, or capture the fstab or systemd mount options into the image with TorizonCore Builder:
nosuid,nodev,noexec
Apply the same options to a separate /data partition if your product uses one.
Container image execution is not blocked by this. With the Docker overlay2 storage driver, the container root filesystem is a separate overlay mount. The kernel evaluates execute and setuid permission against that overlay mount, not against the flags on the backing store under /var/lib/docker, so binaries inside an image still run.
What does inherit noexec and nosuid is a host bind mount from a path on /var into a container, because bind mounts carry the host mount flags. Named volumes under /var/lib/docker/volumes are typically bind-mounted the same way. Audit Compose volumes entries if you need to execute or use setuid binaries from those paths. Host-side tools that unpack and run helpers from under /var would also break under noexec, so test those workflows before fleet rollout.
The OSTree Write Model
Classic hardening guides recommend making the root filesystem read-only. On Torizon OS that advice is misleading. OSTree already makes /usr immutable, while / stays writable so that /etc can be merged across upgrades. Remounting / fully read-only breaks that model.
Instead:
- Treat
/usras read-only operating system content, which is already true on stock Torizon OS. - Ensure applications and containers persist state only under
/var, and/dataif present. - Limit
/etcchanges to configuration that belongs in the OSTree merge layer, and prefer capturing fleet configuration with TorizonCore Builder.
Verify that /usr is read-only. The first command reports ro among the mount options, and the second fails with Read-only file system:
# findmnt -o TARGET,OPTIONS /usr
# touch /usr/write-test
Root Filesystem Integrity
Integrity protection detects tampering with operating system content, whether offline or at runtime. On Torizon OS the supported mechanism is torizon-signed, which uses composefs to provide root filesystem authenticity and integrity as part of the Secure Boot chain of trust.
This is part of the Toradex Secure Boot stack rather than a runtime setting, and it is not something TorizonCore Builder can enable on an otherwise stock image. Generating a Secure Boot enabled image requires a Yocto build using the torizon-signed class. To set it up:
- Follow How to Integrate Secure Boot on Torizon OS and Secure Boot on Torizon OS.
- Configure the composefs signing keys as described in Root Filesystem Protection on Torizon OS.
Once root filesystem protection is active, /etc becomes an in-memory overlay over the pristine /usr/etc from the image, so runtime changes there are discarded on reboot. That affects most of the hardening in this section, including sysctl drop-ins and masked units.
Plan for this before you enable it: build the hardening into the image, and relocate the small number of files that genuinely need to persist outside /etc. Root Filesystem Protection on Torizon OS works through that process in detail.
Data-at-Rest Encryption
If someone can remove the storage medium, an unencrypted /var exposes credentials, container volumes, and application state to offline reading. Encryption protects data at rest. It does not replace access control on a running system.
Use the encryption path that Toradex supports, based on tdx-encrypted and Trusted Keys, usually with a dedicated data partition. See Encryption on Torizon OS and README-encryption.md in the meta-toradex-security layer.
As with Secure Boot, you configure this when building a security-enabled image with Yocto and meta-toradex-security, not through a TorizonCore Builder capture on a stock development image.
The trade-offs are:
| Enabling data-at-rest encryption | Leaving data unencrypted |
|---|---|
| A removed or stolen eMMC or SD card is unreadable without the device-bound key | Simpler image and bring-up, with no key-provisioning pipeline |
| Fits threat models that include offline physical access to storage | Anyone holding the medium can read /var offline, including credentials, volumes, and application state |
| Requires recovery and re-provisioning procedures | No encryption-related recovery or field-replacement complexity |
Enable encryption when your threat model includes offline access to storage and you can operate key provisioning and recovery. In Torizon OS by default, cryptsetup is available but no encrypted devices are configured by default.