Privilege Escalation Bug Lurked in Linux Kernel for 8 Years
A security vulnerability in a driver leading to local privilege escalation in the latest Linux Kernel version was introduced 8 years ago, Check Point reveals.
The security flaw provides a local user with access to a vulnerable privileged driver with the possibility to read from and write to sensitive kernel memory. Tracked as CVE 2018-8781, the vulnerability could be exploited to escalate local privileges, Check Point’s researchers say.
The bug impacts the internal mmap() function defined in the fb_helper file operations of the “udl” driver of “DisplayLink” and was discovered using a simple search.
Because drivers commonly implement their own version of file operation functions, they are prone to implementation errors, and the discovery of this vulnerability is proof of that.
In fact, there are various common vulnerabilities impacting drivers where the mmap() handler is used, such as lack of input validations and Integer-Overflows.
A classic driver, the researchers explain, holds an internal buffer representing the shared memory region with the peripheral device, and should only let the user access memory ranges inside this buffer.
The prototype of the mmap() function includes numerous fields that an attacker can control and developers should perform a series of checks and to avoid possible Integer-Overflows to eliminate issues.
According to Check Point, there are three checks that should be performed: Region start: 0 <= offset < buffer’s end; Region end: buffer’s start <= offset + length <= buffer’s end; and Region start <= Region End.
“In actual fact, the last check can be spared since the Linux kernel will sanitize the supplied length, making it practically impossible to pass the first two checks while still passing the third check,” Check Point says.
The researchers discovered the security flaw while taking a closer look at remap_pfn_range(), a function of high importance, because it maps physical memory pages to the user.
“The video/drm module in the kernel defines a default mmap() wrapper that calls that real mmap() handler defined by the specific driver,” the security researchers note.
The bug is a classic example for an Integer-Overflow: there’s an unsigned offset, thus the first check is skipped, and the calculation “offset + size,” however, can bypass the second check while still using an illegal “offset” value.
As there are only 48 bits of accessible memory on 64-bit machines, the use of a huge “offset” to bypass the check requires making sure that “info->fix.smem_start + offset” will wrap-around to a valid mappable physical address, Check Point also notes.
The vulnerability was verified on an Ubuntu 64-bit virtual machine where a simulated vulnerable driver was uploaded. The driver’s mmap() handler included the implementation to check in each test.
Two consecutive calls to mmap() on the vulnerable driver were made by user-mode code, namely a sanity check and a vulnerability check.
Setting the buffer’s address at the page-aligned physical address of the kernel’s /dev/urandom implementation results in the output providing the correct physical page and the previous physical page, respectively.
Additional checks revealed that it is possible for the user to read and write from/to the mapped pages.
Thus, an attacker could eventually trigger code execution in kernel space, the researchers explain.
“While the vulnerability was found using a simple search, it was introduced to the kernel eight years ago.
This fact can teach us that even on a popular open source project as the Linux Kernel, you could always hope to find vulnerabilities if you know where to search,” Check Point concludes.
The vulnerability was disclosed to the Linux Kernel on March 18 and a patch was issued the same day.
After the patch was verified, the official Linux patch was issued for CVE 2018-8781 on March 21 and was integrated to the Linux Kernel the same day.