Skip to content

Overview

This is a quick technical overview of AppArmor. This page covers a basic overview of AppArmor technical details and provides a jump off point for topic specific pages.

Warning

This document is unfinished, and contains information that is in accurate in that it may have discussion of features that are planned but not implemented.

Versions

There are three main versions of the AppArmor security module that saw any significant Deployment

  • AppArmor 2.0 series (not discussed), based on pcre (Perl Compatible Regular Expressions) and some small kernel hacks that could almost but not always get the pathname right

  • AppArmor 2.1 - 2.3 series - based on dfa (bespoke Deterministic Finite-state Automaton, replaced pcre) and vfs patching

  • AppArmor 2.4+ - based on dfa, creds and security path permission hooks

Many of the details of the 2.1 - 2.3 series are the same as the 2.4 series though the kernel code was significantly reworked.

Components

AppArmor consists of several components.

Kernel space

AppArmor kernel module enforces policy loaded from user space.

---
title: Kernel
---
erDiagram
    KERNEL_MODULE ||..o{ POLICY : enforces

User space

AppArmor parser compiles profiles into a policy as a binary blob, it then loads the binary blob into the kernel.

Initscripts load and stop profiles as a total policy.

---
title: User space
---
erDiagram
    INITSCRIPTS ||..o{ POLICY : loads 
    APPARMOR_PARCER ||..o{ PROFILES : compiles
    POLICY ||--|{ PROFILES : is_compiled_out_of

Libraries

Userspace libraries libraries provide common functionality to AppArmor tools.

  • libaalogparse parses auditd/syslogd messages, understands differences in formatting, presents common interface to events;
  • libapparmor provides stable API for change_hat, aa_change_hat, aa_change_profile, parse_record, and free_record.

Tools

User-facing set of tools for interacting with the lower level bits of AppArmor:

Confinement

AppArmor attaches profiles to every task in the system.

Confined tasks

If a task has a corresponding policy defined and loaded into the kernel, it is considered confined and its behavior is mediated by AppArmor.

If a profile name is a path to an executable, this profile automatically attaches to the executable (see Attached profiles. A task may be confined by multiple profiles: - When a tasks is confined by multiple profiles it permission set is the intersection of all profiles. - Each profile confining an application behaves independently (ie. as though the other profiles were not also being applied). - unconfined profile

Unconfined tasks

If a task has no corresponding policy defined or loaded into the kernel prior to starting, it is considered unconfined, and its behavior is not affected by AppArmor.

Unconfined tasks a special unconfined profile attached to them.

Each profile namespace has a unique unconfined profile which is created when the namespace is created.

The unconfined profiles are used to identify which the namespace unconfined tasks are next in queue for profile attachment.

What an unconfined profile looks like:

 profile unconfined {
     capability *,
     /**        mrwlk,
     /** pix,

     network,
     ipc *,
 }

Mediation

AppArmor mediation is based around the profile.

AppArmor mediation is applied in addition to DAC and can not override DAC checks. When AppArmor is combined with pam_capability, capaility can be granted which can override DAC checks and then AppArmor further restricts.

Internal permissions

AppArmor defines a set of internal permissions that is different than represented in policy.

why no trunc? - minimal value - changing the size of the file, would allow catching some behaviors but doesn't stop a task from destroying data. If a task can write to a file it can overwrite the file with garbage.

mv/cp are equivalent, mv doesn't result in a different labeling than cp. ?? will this remain true for on disk labels??

why no mv/rename permission? Coould be used to enforce where files can be renamed. Eg. rename /foo to /bar, - in reality it has minimum value as it can not be generically enforced from the kernel. renames within a fs/device/partition could be mediated this way but renames across devices are handled as copies. Where the kernel can't “see” the connection of reads and writes being done by user space. Thus a copy could in many cases be used to circumvent a rename rule. A rename rule could be useful in forcing the behavior that a file is created in one part of the file system/device and only ever moved. Ie standard creation and write are not allowed at the destination, but a rename is allowed (but his would break copying to the location).

mapping policy based permissions to internal permission - this is done is ideally done in the parser, but can be done in the loading interface to provide backwards compatibility with older versions of permission maps.

Enforcing permission mapping

AppArmor kernel module is a policy engine, the LSM is considered as the mechanism.

AppArmor does not provide a one to one mapping of DAC permissions to AppArmor permissions

A permission request is done by mapping LSM functions and parameters to an AppArmor permission set.

File object mediation

AppArmor file object mediation is path based but has been slowly evolving towards a hybrid of path and label mediation. Currently AppArmor's uses DAC labeling of files (owner of file, ...) as a secondary condition beyond path name to determine access rights. Using xattr based labeling as another condition is possible and AppArmor will be extended to use them in the future.

rules order independent To determine access permissions to a file ???

Once file access rights are determined opened file descriptors are labeled with profile that they were opened under (dynamically labeled, note this label is not written to disk). This labeling is then used as the primary label for the lifetime of the file descriptor even if the on disk file object is moved (AppArmor does not do any revocation at this time). Any further access checks for the file descriptor are done against the primary label and if this fails, then a secondary revalidation check against the files current name can be done to determine access rights.

revocation/revalidation - at exec time, reload of profile, change_hat

AppArmor uses the path of file objects based mediation as part of its controls. The path of the obPaths are used at open and to revalidate.

  • label open files with profile that opened them - delegation

  • revalidation and change_hat

AppArmor path rules from a labeling perspective

There are two ways to think of AppArmor file rules as labels, either the path as the label or unique dfa accept states as a label.

Path as a label

The path can be thought of as a label - multiple labels per file

Dfa state as label

The best equivalent AppArmor has to a label would be the unique accept state in a dfa. - can intersect profiles to find shared states (labels) - can analyze total policy this way

Revalidation

  • when a file object is accessed that has not been delegated and has not been labeled to match - Relooks up path, treated like opening file at that instant

Mediation without the path

  • network rules - labeling via profile (sid)

Capabilities

AppArmor capability rules allow selective access to a tasks capability set.

 capability dac_override,

Extended capability rules

The extended capability rules allow further restricting what is granted by a capability. Each rule has its own syntax.

Conditionals on owner, user, profile, file type

Examples:

 # only allow dac_override on objects belonging to user1, or user2 this include file and ipc
 # conditional capabilities are scheduled for apparmor 3.0
 owner=(user1,user2) capability dac_override,
 # restricted dac_override
 capability dac_override {
    /file/bar rw,
 }
 capability chown {
   /file/bar (user1, user2),
 }

Network

Network labeling CIPSO

setup network rules to label a socket/packet label is used by ipc rules

uses ipc

IPC

can be done through file and network rules, and/or dynamic labeling based (uses profile label on objects to determine if communication is allowed

 ipc rw /profile,

Specific forms of ipc can be allowed/disallowed by using more specific ipc rules

 ipc signal w (child) /profile,   # only allow sending SIG_CHILD to /profile
 deny ipc signal w (kill) /profile,  # don't allow sending SIG_KILL to /profile

RLIMITS

Delegation ???

  • basic delegation

  • advanced delegation

Matching of UTF-8

user space computation ? -> filenames are just bytes... but with e.g. JIS or BIG5, a byte-shift could have large consequences

Userspace Basics

Policy

Important files /etc/apparmor.d/

Initscripts

Parser

Analyzing AppArmor policy

  • discuss dfa state based analysis, intersecting profiles, etc. - {user,system}x{profile}->{user,system}x{profile} information flow