Skip to content

OAMAC is a prototype Linux security mechanism that enforces origin-aware mandatory access control (MAC) using eBPF LSM. It distinguishes between execution origins such as physical, remote, and service and uses this information to restrict access to sensitive kernel interfaces.

License

Notifications You must be signed in to change notification settings

omeroooor/oamac

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OAMAC: Origin-Aware Mandatory Access Control for Linux

OAMAC is a prototype Linux security mechanism that enforces origin-aware mandatory access control (MAC) using eBPF LSM. It distinguishes between execution origins such as physical, remote, and service and uses this information to restrict access to sensitive kernel interfaces.

This repository contains the core prototype used in the accompanying paper.

  • oamac.bpf.c → eBPF LSM program implementing origin classification and enforcement.
  • oamacctl.c → userspace control tool for managing policies.
  • oamac-load.sh → loader script for attaching the LSM programs and pinning maps.
  • oamac-apply-policies.sh → helper to replay persisted policies at boot.

OAMAC does not require kernel patches and relies only on upstream eBPF LSM support.

Features

  • Classifies processes into origins (physical, remote, service, unknown) using kernel-visible signals.
  • Enforces origin-aware policies at two LSM hooks:
    • lsm/file_open → restrict access to sensitive filesystem paths (e.g., /sys, /proc/sys).
    • lsm/bpf → restrict BPF control-plane operations (e.g., BPF_PROG_LOAD, BPF_MAP_UPDATE_ELEM).
  • Separate policy maps for:
    • Path policies: (origin, prefix) → allow | deny.
    • Interface policies: (origin, interface) → allow | deny.
  • Userspace tool oamacctl to:
    • Add/remove path and interface policies.
    • Manage policies by index.
    • List current policies, optionally filtered by type.
  • Optional persistence via /etc/oamac/policies.conf, replayed at boot.

Requirements

  • Linux kernel with eBPF LSM support enabled (e.g., recent Ubuntu kernel with lsm=landlock,lockdown,yama,bpf,...).
  • clang and llvm for compiling BPF.
  • libbpf-dev and bpftool for building and loading.
  • systemd for the example boot-time integration.

Build

From the oamac/ directory:

# Build the BPF object (assuming x86_64 and vmlinux.h in the current directory)
clang -O2 -g -Wall -target bpf -D__TARGET_ARCH_x86 -I. -c oamac.bpf.c -o oamac.bpf.o

# Build the control tool
clang -O2 -Wall oamacctl.c -o oamacctl -lbpf

On non-x86_64 systems, replace -D__TARGET_ARCH_x86 with the appropriate architecture macro (e.g., __TARGET_ARCH_arm64).

You should now have:

  • oamac.bpf.o
  • oamacctl

Installation (example layout)

The following steps install OAMAC into a conventional layout and configure a systemd oneshot service.

sudo mkdir -p /opt/oamac /etc/oamac

# Deploy BPF object and tools
sudo cp oamac.bpf.o /opt/oamac/
sudo cp oamacctl /usr/local/bin/oamacctl

# Deploy helper scripts
sudo cp oamac-load.sh /usr/local/sbin/oamac-load.sh
sudo cp oamac-apply-policies.sh /usr/local/sbin/oamac-apply-policies.sh
sudo chmod +x /usr/local/sbin/oamac-load.sh /usr/local/sbin/oamac-apply-policies.sh

systemd unit

Create /etc/systemd/system/oamac.service:

[Unit]
Description=Origin-aware MAC (oamac) LSM loader
After=network.target
Wants=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/oamac-load.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable oamac.service
sudo systemctl start oamac.service

Policy configuration and persistence

At runtime, policies live in two eBPF array maps:

  • path_policies for filesystem paths.
  • iface_policies for BPF interfaces.

For convenience, OAMAC supports a simple persistent policy file that is replayed at boot.

/etc/oamac/policies.conf

Each non-empty, non-comment line corresponds directly to an oamacctl invocation without the binary name.

Examples:

# Path policies
path /sys deny remote
path /sys/kernel/btf allow remote

# Interface policies
iface bpf-prog-load deny remote
iface bpf-map-update deny remote

On boot, oamac-apply-policies.sh reads this file and executes:

sudo oamacctl <line>

for each line, repopulating the kernel maps from the declarative configuration.

Using oamacctl

Basic usage (run as root):

# Show all policies
sudo oamacctl list

# Show only path or only interface policies
sudo oamacctl list path
sudo oamacctl list iface

# Add or update a path policy
sudo oamacctl path /sys deny remote
sudo oamacctl path /sys/kernel/btf allow remote

# Remove a path policy by specifying delete
sudo oamacctl path /sys delete remote

# Add interface policies
sudo oamacctl iface bpf-prog-load deny remote
sudo oamacctl iface bpf-map-update deny remote

# Delete an interface policy
sudo oamacctl iface bpf-prog-load delete remote

Index-based operations:

# Set path policy at a specific index
sudo oamacctl set-index path 0 /sys deny remote

# Set interface policy at a specific index
sudo oamacctl set-index iface 0 bpf-map-update deny remote

# Delete entries by index
sudo oamacctl del-index path 0
sudo oamacctl del-index iface 0

Trying the prototype

A minimal end-to-end test after installation:

  1. Configure policies:

    sudo tee /etc/oamac/policies.conf >/dev/null <<'EOF'
    path /sys/kernel/btf allow remote
    path /sys/kernel/btf allow service
    path /sys deny remote
    path /etc/oamac deny remote
    path /etc/oamac deny service
    iface bpf-prog-load deny remote
    iface bpf-map-create deny remote
    iface bpf-map-update deny remote
    iface bpf-prog-load deny service
    iface bpf-map-create deny service
    iface bpf-map-update deny service
    EOF

    Policy rationale:

    • path /sys/kernel/btf allow remote

      • Allows remote tools to read kernel BTF metadata (e.g., for observability) without exposing broader sysfs control surfaces.
      • Must appear before broader /sys denies so it takes precedence.
    • path /sys/kernel/btf allow service

      • Allows service-origin processes (e.g., observability/agent units) to read kernel BTF metadata while keeping broader sysfs control surfaces restricted.
      • Keep this specific allow before broader /sys denies so it takes precedence for service origin as well.
    • path /sys deny remote

      • Denies remote-origin access to sysfs control interfaces by default.
      • Mitigates post-compromise "living off the land" tweaks via sysfs tunables and device control paths.
    • path /etc/oamac deny remote

      • Protects OAMAC configuration and persisted policy files from remote modification.
    • path /etc/oamac deny service

      • Ensures services (non-interactive/background) cannot change OAMAC configuration at runtime; post-boot changes should use PHYSICAL-origin oamacctl.
    • iface bpf-prog-load deny remote

      • Blocks loading new BPF programs from remote-origin processes, closing a powerful kernel control vector after compromise.
    • iface bpf-map-create deny remote

      • Prevents remote-origin creation of new BPF maps.
    • iface bpf-map-update deny remote

      • Prevents remote-origin updates to existing BPF maps, including OAMAC’s policy maps.
    • iface bpf-prog-load deny service

      • Disallows services from loading BPF programs post-boot, keeping kernel control-plane modifications out of non-interactive paths.
    • iface bpf-map-create deny service

      • Disallows services from creating new BPF maps post-boot.
    • iface bpf-map-update deny service

      • Disallows services from modifying BPF maps post-boot; runtime policy management is restricted to PHYSICAL-origin via oamacctl.

    Notes:

    • Place specific allows (e.g., /sys/kernel/btf allow remote) before broad denies (e.g., /sys deny remote) because the first matching rule wins.
    • Apply these strict interface/path denies as the final step of the boot oneshot so the loader can run before lockdown.
  2. Apply policies without restarting:

    sudo /usr/local/sbin/oamac-apply-policies.sh
    sudo oamacctl list

    Note: After initialization, policies can only be removed via oamacctl. Avoid restarting oamac.service once SERVICE/REMOTE BPF denies are in place—the SERVICE-origin loader may be blocked. If a restart is required, temporarily relax the SERVICE/REMOTE BPF denies from a PHYSICAL session, restart, then re-apply and lock down again.

  3. From a remote SSH session, attempt to access /sys or load a BPF program; access should be denied according to policy.

  4. From a local console/GUI terminal, perform the same actions; they should succeed if origin is classified as physical.

UNKNOWN origin and boot-time tasks

OAMAC is implemented entirely using upstream Linux features (eBPF LSM) without kernel modifications. As a result, processes that already exist before OAMAC is initialized (e.g., early boot and core system services) cannot be retroactively classified. These tasks are conservatively assigned the UNKNOWN origin.

To preserve boot safety and avoid disrupting existing system behavior, origin-aware policies are not applied to UNKNOWN by default in the current prototype. In practice, this means:

  • UNKNOWN includes both:
    • Early bootstrap tasks and long-lived system services that started before OAMAC was loaded.
    • Genuinely ambiguous contexts whose origin cannot be determined from available provenance.
  • The prototype intentionally does not enforce restrictive policies on UNKNOWN out of the box to avoid breaking boot or critical services.

If you choose to configure policies that deny or heavily restrict UNKNOWN, you must treat this as an advanced and potentially unsafe configuration:

  • You may inadvertently block access for essential system daemons or services that inherited the UNKNOWN origin during boot.
  • Misconfigured UNKNOWN policies can cause subtle or hard failures (e.g., services silently failing to access /sys or /proc).

Recommendation:
Unless you fully understand which processes in your environment are labeled UNKNOWN and have validated their behavior, do not deploy restrictive policies for UNKNOWN on production or critical systems. Test such configurations in isolated environments first.

Caveats

  • This is a research prototype, not a hardened production system.
  • It assumes a trusted kernel and correct eBPF LSM configuration.
  • Misconfigured policies can lock out legitimate administration; test on non-critical systems first.

For a deeper discussion of the threat model, origin classification, and evaluation, see the accompanying paper.

About

OAMAC is a prototype Linux security mechanism that enforces origin-aware mandatory access control (MAC) using eBPF LSM. It distinguishes between execution origins such as physical, remote, and service and uses this information to restrict access to sensitive kernel interfaces.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published