Course contentsShow
← Linux
Lesson 969 of 1,8199. Security Hardening and Mandatory Access ControlFree lesson

Handling Shared Library Pathing in Profiles

Ensure all required system libraries are correctly reachable under restricted directory constraints.

In this lesson, you will learn how to ensure that your AppArmor-confined applications can successfully locate and load their required shared libraries when operating under strict directory constraints.

The Challenge of Library Resolution

When you restrict an application's file system access using AppArmor, you often limit it to specific directories (like /usr/bin/ or /opt/myapp/). However, applications are rarely self-contained; they rely on shared libraries (.so files) located in system-wide directories like /lib/, /usr/lib/, or custom vendor paths.

If your profile restricts access too aggressively, the dynamic linker—responsible for loading these dependencies at runtime—will be blocked by the kernel. Even if the application binary itself is permitted to run, it will crash immediately upon startup because it cannot "see" the libraries required to execute its instructions.

Configuring Path Access for Libraries

To resolve this, you must grant the profile explicit permission to read the directories where your application’s dependencies reside. While you could technically whitelist every individual library file, it is cleaner and more robust to use directory-level access with the r (read) and m (map) permissions.

The m permission is particularly important here: it allows the memory management unit to map the library file into the process's address space for execution.

Consider a profile that needs access to standard system libraries and a custom local library:

profile my-secure-app /usr/bin/my-secure-app {
  # Allow access to standard system libraries
  /lib/x86_64-linux-gnu/*.so* mr,
  /usr/lib/x86_64-linux-gnu/*.so* mr,

  # Allow access to a specific vendor-provided library directory
  /opt/vendor/lib/*.so* mr,

  # Rest of your profile rules...
}

Best Practices

  1. Use Globbing: As shown above, using *.so* allows you to cover versioned library files (e.g., libc.so.6) without creating a new rule every time a library updates.
  2. Limit to Read/Map: Never grant w (write) permissions to library directories. Shared libraries should always be immutable to the application using them to prevent local code injection attacks.
  3. Audit Denials: If your application fails to start, check dmesg or /var/log/audit/audit.log for DENIED messages involving m permissions; these usually point to missing library paths.

Key Takeaway: To ensure application stability under strict profiles, you must explicitly permit read and map (mr) access to the specific directories containing required shared libraries.