CVE-2016-0728 – Linux Kernel Flaw

CVE-2016-0728 is the latest zero-day flaw discovered in linux kernel which affects millions of users across the world. The vulnerability has been there since several years and was discovered only recently. This flaw exists in all the linux kernel versions 3.8 and later. CVE-2016-0728 is basically a memory-leak vulnerability, where the flaw exists within the Linux’s security features-keyrings facility. CVE-2016-0728 is caused by a reference leak in the keyrings facility. An attacker can exploit the vulnerability by running a malicious linux application on the affected device. If successfully exploited, the vulnerability can allow attacker to get root access to the operating system, enabling them to do anything what a root user is allowed to do.

This vulnerability exists actually due to error in the “join_session_keyring” function within process_keys.c script of kernel code. Below is buggy code snippet taken from process_keys.c script for vulnerable Linux Kernel 3.18.x (3.18.25) found at here.

Upon analyzing above code it is clear if a thread tries to set its current session keyring with the same one already set, the control passes over to error2 label. But there is no way that the reference for the keyring gets discarded in this case and hence resulting in reference leak error. Below code explains the scenario.
The above mentioned execution does not have a call to key_put() function so as to discard the reference for the keyring resulting in memory leak. This memory leak error can be carefully crafted to create a fully-working exploit escalating users priveleges. The sequence of steps which exploit would need to do include:

1) Get hold of reference to key object.
2) Somehow overflow internal RefCount in usage field.
3) Free keyring object and hold a reference to it.
4) Allocating and controlling the kernel object that will override the freed keyring object.
5) Using the reference to the old key object and trigger code execution.

A fully Working exploit can be found here which successfully escalates privileges from a local user to root.

Check for Vulnerable Kernel:
CVE-2016-0728 is a memory leak vulnerability which is triggered when a thread tries to replace its current session keyring with the keyring that’s already set as its session keyring. A simple program to test for this vulnerablity can be found here.
The program simply tries to set 100 times same keyring name that already exists to trigger the memory leak. If the program successfully creates references for the same keyring name, the running kernel is vulnerable.

Steps to Check include:
1) Compile provided test C-Code.
2) Before running test script check once the Keys that are already set. It can be done by checking contents of file /proc/keys that lists out all the keys that are currently viewable.
3) Run the created test-executable.
4) Check the contents of /proc/keys once again.
5) If 100 references for leaked-keyring are present,like one shown below, Kernel is vulnerable.