Sequoia: A Local Privilege Escalation Vulnerability in Linux’s Filesystem Layer (CVE-2021-33909)
Last updated on: December 22, 2022
The Qualys Research Team has discovered a size_t-to-int type conversion vulnerability in the Linux Kernel’s filesystem layer affecting most Linux operating systems. Any unprivileged user can gain root privileges on a vulnerable host by exploiting this vulnerability in a default configuration.
About Linux Filesystem
A file system is an organization of data and metadata on a storage device. It controls how the data is stored and retrieved, and its most important function is to manage user data. The Linux file system interface is implemented as a layered architecture, separating the user interface layer from the file system implementation and from the drivers that manipulate the storage devices. It is the most important function of any operating system and is ubiquitous on all major Linux operating systems.
Impact
Successful exploitation of this vulnerability allows any unprivileged user to gain root privileges on the vulnerable host. Qualys security researchers have been able to independently verify the vulnerability, develop an exploit, and obtain full root privileges on default installations of Ubuntu 20.04, Ubuntu 20.10, Ubuntu 21.04, Debian 11, and Fedora 34 Workstation. Other Linux distributions are likely vulnerable and probably exploitable.
As soon as the Qualys research team confirmed the vulnerability, Qualys engaged in responsible vulnerability disclosure and coordinated with vendor and open-source distributions to announce the vulnerability.
Disclosure Timeline
- 2021-06-09: The Qualys Research Team (QRT) sent advisories for CVE-2021-33909 and CVE-2021-33910 to Red Hat Product Security (the two vulnerabilities are closely related, and the systemd-security mailing list is hosted by Red Hat).
- 2021-07-06: QRT sent advisories, and Red Hat sent the patches they wrote, to the linux-distros@openwall mailing list.
- 2021-07-13: QRT sent advisory for CVE-2021-33909, and Red Hat sent the patch they wrote, to the security@kernel mailing list.
- 2021-07-20: Coordinated Release Date (12:00 PM UTC).
Proof of Concept Video
Technical Details
The Linux kernel’s seq_file interface produces virtual files that contain sequences of records (for example, many files in /proc are seq_files, and records are usually lines). Each record must fit into a seq_file buffer, which is therefore enlarged as needed, by doubling its size at line 242 (seq_buf_alloc() is a simple wrapper around kvmalloc()):
------------------------------------------------------------------------ 168 ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter) 169 { 170 struct seq_file m = iocb->ki_filp->private_data; … 205 / grab buffer if we didn't have one */ 206 if (!m->buf) { 207 m->buf = seq_buf_alloc(m->size = PAGE_SIZE); … 210 } … 220 // get a non-empty record in the buffer … 223 while (1) { … 227 err = m->op->show(m, p); … 236 if (!seq_has_overflowed(m)) // got it 237 goto Fill; 238 // need a bigger buffer … 240 kvfree(m->buf); … 242 m->buf = seq_buf_alloc(m->size <<= 1); … 246 } ------------------------------------------------------------------------
This size multiplication is not a vulnerability in itself, because m->size is a size_t (an unsigned 64-bit integer, on x86_64), and the system would run out of memory long before this multiplication overflows the integer m->size. Unfortunately, this size_t is also passed to functions whose size argument is an int (a signed 32-bit integer), not a size_t. For example, the show_mountinfo() function (which is called at line 227 to format the records in /proc/self/mountinfo) calls seq_dentry() (at line 150), which calls dentry_path() (at line 530), which calls prepend() (at line 387):
------------------------------------------------------------------------ 135 static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) 136 { … 150 seq_dentry(m, mnt->mnt_root, " \t\n\"); ------------------------------------------------------------------------ 523 int seq_dentry(struct seq_file *m, struct dentry *dentry, const char *esc) 524 { 525 char *buf; 526 size_t size = seq_get_buf(m, &buf); … 529 if (size) { 530 char *p = dentry_path(dentry, buf, size); ------------------------------------------------------------------------ 380 char *dentry_path(struct dentry *dentry, char *buf, int buflen) 381 { 382 char *p = NULL; … 385 if (d_unlinked(dentry)) { 386 p = buf + buflen; 387 if (prepend(&p, &buflen, "//deleted", 10) != 0) ------------------------------------------------------------------------ 11 static int prepend(char **buffer, int *buflen, const char *str, int namelen) 12 { 13 *buflen -= namelen; 14 if (*buflen < 0) 15 return -ENAMETOOLONG; 16 *buffer -= namelen; 17 memcpy(*buffer, str, namelen); ------------------------------------------------------------------------
As a result, if an unprivileged local attacker creates, mounts, and deletes a deep directory structure whose total path length exceeds 1GB, and if the attacker open()s and read()s /proc/self/mountinfo, then:
- in seq_read_iter(), a 2GB buffer is vmalloc()ated (line 242), and show_mountinfo() is called (line 227);
- in show_mountinfo(), seq_dentry() is called with the empty 2GB buffer (line 150);
- in seq_dentry(), dentry_path() is called with a 2GB size (line 530);
- in dentry_path(), the int buflen is therefore negative (INT_MIN, -2GB), p points to an offset of -2GB below the vmalloc()ated buffer (line 386), and prepend() is called (line 387);
- in prepend(), *buflen is decreased by 10 bytes and becomes a large but positive int (line 13), *buffer is decreased by 10 bytes and points to an offset of -2GB-10B below the vmalloc()ated buffer (line 16), and the 10-byte string “//deleted” is written out of bounds (line 17).
Solution
Given the breadth of the attack surface for this vulnerability, Qualys recommends users apply patches for this vulnerability immediately.
Qualys customers can search the vulnerability knowledgebase for CVE-2021-33909 to identify all the QIDs and assets vulnerable for this vulnerability.
If you are not a customer, start your free Qualys VMDR trial to get full access to the QIDs (detections) for CVE-2021-33909, so you can identify your vulnerable assets.
Qualys Coverage
Qualys is releasing the QIDs in the table below as they become available starting with vulnsigs version VULNSIGS-2.5.237-3 and in Linux Cloud Agent manifest version lx_manifest-2.5.237.3-2
QID | Title | VulnSigs Version |
---|---|---|
750847 | OpenSUSE Security Update for the Linux Kernel (openSUSE-SU-2021:2409-1) | VULNSIGS-2.5.237-3 / lx_manifest-2.5.237.3-2 |
750844 | SUSE Enterprise Linux Security Update for kernel (SUSE-SU-2021:2407-1) | VULNSIGS-2.5.237-3 / lx_manifest-2.5.237.3-2 |
178710 | Debian Security Update for linux (DSA 4941-1) | VULNSIGS-2.5.237-3 / lx_manifest-2.5.237.3-2 |
375710 | Linux Kernel Local Privilege Escalation Vulnerability (Sequoia) | VULNSIGS-2.5.237-3 / lx_manifest-2.5.237.3-2 |
Discover Vulnerable Linux Servers Using Qualys VMDR
Identify Assets Running Linux Kernel
The first step in managing these critical vulnerabilities and reducing risk is identification of assets running Linux OS. Qualys VMDR makes it easy to identify such assets.
Query: operatingSystem.category1:`Linux`
Once the hosts are identified, they can be grouped together with a ‘dynamic tag’, let’s say – “Linux Servers”. This helps in automatically grouping existing hosts with the above vulnerabilities as well as any new Linux assets that spin up in your environment. Tagging makes these grouped assets available for querying, reporting and management throughout the Qualys Cloud Platform.
Prioritize Based on RTIs
Using Qualys VMDR, the vulnerabilities can be prioritized using the following real-time threat indicators (RTIs):
Predicted_High_Risk
Privilege_Escalation
Easy_Exploit
High_Lateral_Movement
Detect Impacted Assets with Threat Protection
VMDR also enables you to automatically map assets vulnerable to these vulnerabilities using Threat Protection.
Dashboard
With VMDR Unified Dashboard, you can track this vulnerability, their impacted hosts, their status and overall management in real time. With trending enabled for dashboard widgets, you can keep track of these vulnerabilities trends in your environment using the “Sequoia” Dashboard.
View and download the “Sequoia” dashboard:
Vendor References
https://www.qualys.com/2021/07/20/cve-2021-33909/sequoia-local-privilege-escalation-linux.txt
Frequently Asked Questions (FAQs)
What versions are vulnerable?
All Linux kernel versions from 2014 onwards are vulnerable.
Will the Qualys Research Team publish exploit code for this vulnerability?
A PoC is attached with the advisory and available at https://www.qualys.com/research/security-advisories/.
Are there any mitigations for this vulnerability?
The following mitigations prevent only our specific exploit from working (but other exploitation techniques may exist); to completely fix this vulnerability, the kernel must be patched.
- Set /proc/sys/kernel/unprivileged_userns_clone to 0, to prevent an attacker from mounting a long directory in a user namespace. However, the attacker may mount a long directory via FUSE instead; we have not fully explored this possibility, because we accidentally stumbled upon CVE-2021-33910 in systemd: if an attacker FUSE-mounts a long directory (longer than 8MB), then systemd exhausts its stack, crashes, and therefore crashes the entire operating system (a kernel panic).
- Set /proc/sys/kernel/unprivileged_bpf_disabled to 1, to prevent an attacker from loading an eBPF program into the kernel. However, the attacker may corrupt other vmalloc()ated objects instead (for example, thread stacks), but we have not investigated this possibility.
Why is the vulnerability named “Sequoia”?
The bug is in Linux’s seq_file interface, and “Sequoia sempervirens” is a tree that has wide-spreading roots: a pun on the bug’s deep directory tree that yields root privileges.
Referring to below statement “Given the breadth of the attack surface for this vulnerability, Qualys recommends users apply patches for this vulnerability immediately”, are there any patches available from vendors yet or just mitigation steps provided by Qualys Research Team?