ASA-2018-00048 – Linux kernel: Broken uid/gid mapping for nested user namespaces with > 5 ranges


Allele Security Alert

ASA-2018-00048

Identifier(s)

ASA-2018-00048, CVE-2018-18955

Title

Broken uid/gid mapping for nested user namespaces with > 5 ranges

Vendor(s)

Linux foundation

Product(s)

Linux kernel

Affected version(s)

Linux kernel versions before 4.20

Linux kernel versions 4.18.x before 4.18.19
Linux kernel versions 4.19.x before 4.19.2

Linux kernel versions since the following commit:

userns: bump idmap limits to 340
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6397fac4915ab3002dc15aae751455da1a852f25

Fixed version(s)

Linux kernel version 4.20

Linux kernel version 4.18.19
Linux kernel version 4.19.2

Linux kernel versions with the following commit applied:

userns: also map extents in the reverse map to kernel IDs

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d2f007dbe7e4c9583eea6eb04d60001e85c6f1bd

Proof of concept

Yes

Description

A flaw was found in the Linux kernel where map_write() in kernel/user_namespace.c allows privilege escalation as it mishandles nested user namespaces with more than 5 UID or GID ranges. An unprivileged user with CAP_SYS_ADMIN in an affected user namespace can bypass access controls on resources outside the namespace. This is possible because a user/group id transformation takes place properly for the namespaced-to-kernel direction but not for the kernel-to-namespaced direction.

Technical details

commit 6397fac4915a (“userns: bump idmap limits to 340”) increases the number of possible uid/gid mappings that a namespace can have from 5 to 340. This is implemented by switching to a different data structure if the number of mappings exceeds 5: Instead of linear search over an unsorted array of struct uid_gid_extent, binary search over a sorted array of struct uid_gid_extent is used. Because ID mappings are queried in both directions (kernel ID to namespaced ID and namespaced ID to kernel ID), two copies of the array are created, one per direction, and they are sorted differently.

In map_write(), at first, during the loop that calls insert_extent(), the member lower_first of each struct uid_gid_extent contains an ID in the parent namespace. Later, map_id_range_down() is used in a loop to replace these IDs in the parent namespace with kernel IDs.

The problem is that, when the two sorted arrays are used, the new code omits the ID transformation for the kernel->namespaced mapping; only the namespaced->kernel mapping is transformed appropriately.

The current logic first clones the extent array and sorts both copies, then maps the lower IDs of the forward mapping into the lower namespace, but doesn’t map the lower IDs of the reverse mapping.

This means that code in a nested user namespace with > 5 extents will see incorrect IDs. It also breaks some access checks, like inode_owner_or_capable() and privileged_wrt_inode_uidgid(), so a process can incorrectly appear to be capable relative to an inode.

To fix it, we have to make sure that the “lower_first” members of extents in both arrays are translated; and we have to make sure that the reverse map is sorted *after* the translation (since otherwise the translation can break the sorting).

Credits

Jann Horn (Google Project Zero)

Reference(s)

Linux: broken uid/gid mapping for nested user namespaces with >5 ranges
https://bugs.chromium.org/p/project-zero/issues/detail?id=1712

Linux kernel: broken uid/gid mapping for nested user namespaces with >5 ranges (CVE-2018-18955; since 4.15; fixed in 4.18.19 and 4.19.2)
https://seclists.org/oss-sec/2018/q4/150

userns: also map extents in the reverse map to kernel IDs

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d2f007dbe7e4c9583eea6eb04d60001e85c6f1bd

userns: bump idmap limits to 340
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6397fac4915ab3002dc15aae751455da1a852f25

userns: also map extents in the reverse map to kernel IDs
https://github.com/torvalds/linux/commit/d2f007dbe7e4c9583eea6eb04d60001e85c6f1bd

userns: bump idmap limits to 340
https://github.com/torvalds/linux/commit/6397fac4915ab3002dc15aae751455da1a852f25

Linux 4.20
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.20

Linux 4.18.19
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.18.19

Linux 4.19.2
https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.19.2

CVE-2018-18955 - Red Hat Customer Portal
https://access.redhat.com/security/cve/CVE-2018-18955

CVE-2018-18955 in Ubuntu
https://people.canonical.com/~ubuntu-security/cve/CVE-2018-18955.html

CVE-2018-18955 | SUSE
https://www.suse.com/security/cve/CVE-2018-18955

CVE-2018-18955
https://security-tracker.debian.org/tracker/CVE-2018-18955

CVE-2018-18955
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-18955

CVE-2018-18955
https://nvd.nist.gov/vuln/detail/CVE-2018-18955

If there is any error in this alert or you wish a comprehensive analysis, let us know.

Last modified: November 29, 2019

We are not responsible for any data loss, device corruption or any other type of issue due to the use of any information mentioned in our security alerts.