[spec] Unprivileged user namespace restrictions via AppArmor in Ubuntu 23.10

Index SE045
Title Unprivileged user namespace restrictions via AppArmor in Ubuntu
Status Pending Review
Authors Alex Murray
Type Process
Created 2023-05-24

Abstract

Access to unprivileged user namespaces have become too much of a security threat for Ubuntu. The upstream AppArmor project recently introduced a mechanism to allow the use of unprivileged user namespaces to only those applications that both require the access and are appropriately confined by AppArmor (and to deny access to all other applications). It is proposed that this mechanism should be implemented in Ubuntu 23.10 by default to protect users without degrading availability of this feature to legitimate applications that require it.

Rationale

User namespaces are a kernel mechanism to isolate user IDs and other security-relevant attributes within a namespace. In particular this allows a user ID of 0 (ie. root) within the user namespace which is then mapped to their unprivileged user ID outside of the namespace. Within the isolated namespace the user then has access to root-like privileges but these are then bounded only within that namespace and cannot (in theory) allow them to influence the host system outside that namespace. Access to user namespaces and hence these isolated root-like capabilities are a feature of the kernel that can be used to replace many of the uses of setuid and setgid programs, and also allow for applications to create more secure sandboxes themselves.

However while unprivileged user namespaces have been beneficial by reducing the need for setuid and setguid processes they expose kernel interfaces that are normally restricted to processes with privileged capabilities (root) to use by unprivileged users. Exposing more kernel interfaces than necessary to a process increases the kernel attack surface and introduces additional security risks as a result. Unprivileged user namespaces are now often used as a step in several privilege escalation exploit chains as they provide access to various kernel subsystems to nominally unprivileged users within a user namespace where that user can act as root.

This has led to the easy exploitation of many real world CVEs by unprivileged users. If unprivileged user namespaces had not been available, these would only have been able to be exploited by the privileged root user. Examples (to pick a few):

  • CVE-2022-0185: to exploit, need to be able to mount a filesystem, granted by CAP_SYS_ADMIN in a user namespace.
  • CVE-2022-1015: to exploit, need to be able to add netfilter rules, granted by CAP_NET_ADMIN in a new user and network namespace.
  • CVE-2022-2078: to exploit, need to be able to add netfilter rules, granted by CAP_NET_ADMIN in a new user and network namespace.
  • CVE-2022-24122: reference counting error when leaving a user namespace.
  • CVE-2022-25636: to exploit, need to be able to add netfilter rules, granted by CAP_NET_ADMIN in a new user and network namespace.
  • CVE-2020-14386: to exploit, need to interact with AF_PACKET, granted by CAP_NET_RAW in a new user namespace.

Several distros (including Ubuntu, Debian and Arch Linux) carry a kernel patch (that has not been accepted by the upstream kernel developers) that allows for a sysctl to disable unprivileged user namespaces to try and mitigate this risk. Unfortunately the sysctl provides an all or nothing approach as it disables access to unprivileged user namespaces entirely. Disabling unprivileged user namespaces might stop an exploit but can also break applications that legitimately use and rely on access to them.

With introduction of restricted unprivileged user namespaces AppArmor can be used to selectively allow and disallow unprivileged user namespaces for individual applications. AppArmor policy is used to selectively control access to unprivileged user namespaces on a per applications basis, and then deny access to all other applications.

Specification

Enabling AppArmor enforcement of user namespace restrictions within Ubuntu requires changes to the following components within Ubuntu:

Linux kernel source package(s)

Support for LSM mediation of user namespaces was merged into the upstream Linux kernel for the 6.1 release. However, the required changes to allow AppArmor to make use of this are not yet upstream. As such the linux (and associated) Linux kernel source packages in Ubuntu will require SAUCE patches to enable this support. These were integrated into the 6.2 Lunar kernel, tracked in Launchpad bug https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2012136.

These patches introduce a new sysctl named kernel.apparmor_restrict_unprivileged_userns which is used to enable / disable AppArmor enforcement of user namespace restrictions at runtime. This sysctl is currently not enabled (via a value of 0). As such, this sysctl should be changed to be enabled by default (via a default value of 1) so that AppArmor is configured to restrict user namespaces for all unconfined applications. However, instead of enabling this directly in the kernel configuration, instead it should be enabled via a sysctl.d configuration file, as detailed below.

Finally, an additional kernel patch will also be required to ensure that a malicious application cannot simply transition itself into an existing AppArmor profile that grants the new userns, permission. This is also detailed below.

apparmor source package

The apparmor source package in Ubuntu contains the userspace components of AppArmor, including the apparmor_parser binary, along with the associated configuration and default policies and abstractions for the system. It also contains a set of policy/features ABI.

During the kinetic development cycle, apparmor-3.0.7-1ubuntu2 introduced support within apparmor_parser for the userns permission. This allows AppArmor profiles / policies to specify the userns, permission as follows:

userns,

When specified in this manner, an application that is confined by such an AppArmor profile will be allowed to create new unprivileged user namespaces.

However, the default ABI of this version of apparmor_parser does not contain support for the userns feature, and so profiles which do not contain this userns, permission will also silently be granted this permission as well. Similarly, the apparmor parser configuration in Ubuntu is hard-coded to use an ABI that also does not contain the userns feature either.

Therefore, the apparmor source package will need to be updated to include an ABI that contains the userns feature, and the parser configuration within the package will also need to be updated so that by default this new ABI is used when compiling AppArmor profiles. This will ensure that policies that do not specify this new userns, permission are appropriately denied this permission, and do not silently get “upgraded” to include it.

The recent upstream release of AppArmor 4.0-alpha1 introduced a new feature to allow profiles to be tagged with the unconfined flag. This designates the profile to essentially act like the unconfined mode for AppArmor, where an application is not restricted. As seen above, the new kernel sysctl does place a restriction on unconfined applications, by denying them the ability to create unprivileged user namespaces by default. In this case, a profile which specified the unconfined flag and no additional permissions would be blocked from using unprivileged user namespaces. However, when combined with the userns permission above, an application confined by such a profile would then be allowed to use unprivileged user namespaces and not be confined in any other way. Whilst this does not achieve any meaningful confinement of the application, it does allow such applications to continue to use unprivileged user namespaces and avoids the risk of introducing any regression in functionality through the use of an AppArmor profile that was inadvertently too restrictive. It is suggested that this approach will likely be the most appropriate for the majority of applications that legitimately require the use of unprivileged user namespaces, compared to a complete AppArmor profile.

AppArmor 4.0-alpha1 also contains a new ABI named abi/4.0 that lists the full set of features supported by the current 6.2 kernel in Ubuntu, as well as support for the userns feature. The apparmor source package in 23.10 should be upgraded to at least 4.0-alpha1 to ensure these features can be used, which would remove the need to specifically add a new ABI as mentioned above, since the 4.0 ABI can be used directly from the upstream AppArmor release.

Such a profile (for the /usr/bin/flatpak binary) would look like the following:

abi <abi/4.0>,

/usr/bin/flatpak flags=(unconfined) {
    allow userns create,
}

To ensure that a malicious application cannot simply use aa-exec or aa_change_profile() to switch itself into an existing AppArmor profile that contains the userns, permission, an additional kernel patch will be required. This patch will change the behaviour of the change_profile implementation within the kernel, such that when an unconfined application transitions into a new profile, this profile will be stacked within the existing unconfined profile, such that it cannot be more permissive than the original profile and hence cannot make use of the userns, permission within the stacked sub-profile. This restriction will not apply to processes with the CAP_MAC_ADMIN capability, and will be able to be disabled via an additional sysctl knob.

apparmor-profiles binary package

The apparmor-profiles binary package (from the apparmor source package) contains a set of AppArmor profiles for various applications / packages which are maintained in the upstream apparmor project on a best-effort basis - they are generally not specifically maintained in Ubuntu and so may contain omissions or errors when used in Ubuntu. As such, a best-effort attempt should be made to check whether the applications confined by these profiles require the use of unprivileged user namespaces. For those applications that are identified to have a legitimate use for this permission, their associated profile within this source package should be updated to include the new userns, permission as specified earlier.

apparmor-profiles-extra source package

The apparmor-profiles-extra source package contains an additional set of AppArmor profiles for various packages across the Ubuntu archive. These are generally not well maintained and not necessarily up-to-date. As such, a best-effort attempt should be made to check whether the applications confined by these profiles require the use of unprivileged user namespaces. For those applications that are identified to have a legitimate use for this permission, their associated profile within this source package should be updated to include the new userns, permission as specified earlier.

Various other source packages within Ubuntu

Whilst the aforementioned apparmor-profiles-extra package contains a set of AppArmor profiles for some applications, many other applications ship their own AppArmor profile directly within their own package. Some of these packages may have a legitimate need for access to unprivileged user namespaces, and so these packages will need to be identified and their associated AppArmor profiles updated to include this new permission.

There may also be other packages within Ubuntu that also require unprivileged user namespace access but that do not have an existing AppArmor profile. Similarly, these applications will need to be identified, and then have an associated AppArmor profile generated for them. This profile could either use the flags=(unconfined) approach described above (to simply tag the application as requiring the use of unprivileged user namespaces but without confining it in any way), or it could aim to be a complete profile for the application. In the latter case, this profile should specify the minimum set of permissions required for the application to operate in its default configuration and environment, along with the ability for the profile to be customised by the system administrator via the use of a local profile snippet. An example of this is seen in the rsyslog package in lunar - this local file is created automatically via dh_apparmor via an appropriate entry in debian/rules. As a general rule, the use of an overly permissive AppArmor profile should be avoided, since this could be abused by malware etc to transition to such a permissive profile and then use this extra permission to gain access to unprivileged user namespaces or perform other malicious actions on the system.

To identify applications within the Ubuntu archive that require the use of unprivileged user namespaces, a combination of static analysis and dynamic testing should be used. Either the work-in-progress, internal-only Ubuntu Code Search instance (or as Ubuntu is based on Debian, Debian Code Search) can be used to search for applications that use the unshare() or clone() system calls with the CLONE_NEWUSER argument. These can be safely assumed to require this permission and so should have any existing AppArmor profile updated if one already exists, or have a profile created from scratch to include this permission. For each package that is identified as using user namespaces, any packages which make use of these packages will also need to be evaluated. This should be done by first checking the reverse-depends of the package to identify other packages that require that package. New or updated AppArmor profiles for these second-level packages may also be required (and similarly any packages which use those packages etc).

Those applications should then be tested through a combination of manual testing (including manually exercising the application under normal usage scenarios, as well as running any test suites etc) and automatic testing via any DEP8/autopkgtest tests or similar.

Once all identified applications have been updated and tested, then the kernel sysctl should be enabled so that enforcement is done by default.

NOTE that until Debian Import Freeze on 2023-08-17 new packages from Debian get automatically imported into the Ubuntu archive - so the above analysis will need to be repeated after that date to ensure any NEW packages the landed between the time of the initial analysis and this date are not missed.

Summary of steps to achieve this specification

  1. Update the apparmor source package in Ubuntu to at least 4.0-alpha1 to include support for the new 4.0 ABI as well as the unconfined flag. The default /etc/apparmor/parser.conf configuration file should also be updated to specify this new ABI by default and include associated selftests within the apparmor source package to test this feature.
  2. Search for and identify all packages within the Ubuntu archive that make use of unprivileged user namespaces
  3. Create new / update existing AppArmor profiles for all the identified packages to include the new userns AppArmor permission and ensure these all specify the new ABI, and ship these within the apparmor source package.
  4. Make an announcement on the ubuntu-devel mailing list and the Ubuntu Discourse describing this new feature and asking interested users / developers to test it (with a particular mention to ask for testing of third-party packages which are not distributed in the Ubuntu archive)
  5. Update the apparmor source packages to enable the kernel.apparmor_restrict_unprivileged_userns sysctl by default by including a new file named /usr/lib/sysctl.d/10-apparmor.conf that contains the following contents:
# AppArmor restrictions of unprivileged user namespaces
# Restrict the use of unprivileged user namespaces to applications
# which have an AppArmor profile loaded which specifies the userns
# permission. All other applications (whether confined by AppArmor
# or not) will be denied the use of unprivileged user namespaces.
#
# See https://gitlab.com/apparmor/apparmor/-/wikis/unprivileged_userns_restriction
#
# If it is desired to disable this restriction, it is preferable to
# create an additional file named /etc/sysctl.d/20-apparmor.conf
# which will override this current file and sets this value to 0
# rather than editing this current file
kernel.apparmor_restrict_unprivileged_userns = 1

along with details of what this feature is and why it is enabled by default.

NOTE: It was chosen to include this enablement in the apparmor source package itself, rather than in the kernel, since this ensures that if the apparmor package is uninstalled, this file in /usr/lib/sysctl.d/10-apparmor.conf is then also uninstalled and the feature is turned off. Otherwise, if the feature is enabled in the kernel but the apparmor binary package is uninstalled, the system is left without an associated apparmor_parser and profiles etc, and thus all applications will be treated as unconfined and be blocked by the kernel from using unprivileged user namespaces. It was also chosen to place this enablement in /usr/lib/sysctl.d/ rather than just /etc/sysctl.d/ so that it does not get confused as a conffile and hence kept when the package is removed.

  1. Create a set of documentation to guide upstreams, third party developers and users of third party applications which make use of unprivileged user namespaces how they can configure and deploy their applications on Ubuntu when a system is configured to restrict unprivileged user namespaces.

Further Information

It may also be necessary to update applications that are not part of the Ubuntu archive to include this permission as well. This is already underway for snaps and snapd via the new userns interface. However, for applications distributed outside of Ubuntu, it may be necessary to directly reach out to their upstream to warn them of this potentially breaking change. As part of this, guidance should be provided to the upstream on how to ensure their application will work correctly when deployed on a Ubuntu system that enforces this new user namespace restriction.

4 Likes

NOTE: edited on 2023-08-10 to add details about an additional kernel change required to ensure unconfined applications get stacked within any chosen profile via change_profile such that a malicious application should not be able to abuse an existing permissive profile on the system to gain access to unprivileged user namespaces.

NOTE: edited on 2023-08-16 to remove the additional placeholder /etc/sysctl.d/20-apparmor.conf file and instead mention this in the comment for the existing /usr/lib/sysctl.d/10-apparmor.conf file so that it can be created if/when needed by the system administrator. This avoid having to ship yet another conffile.