xorl %eax, %eax

CVE-2018-7273: Linux kernel floppy information leak

leave a comment »

This was a simple information leak vulnerability in the floppy driver that was reported by Brian Belleville to the Linux kernel. Technically, an attacker could trigger show_floppy() calls in the floppy driver to reveal sensitive kernel addresses (such as global variable pointers and function addresses) which can be used to identify the required offsets and consequently, bypass protections like KASLR. You can see drivers/block/floppy.c below.

static void show_floppy(void)
{
    int i;

    pr_info("\n");
    pr_info("floppy driver state\n");
   ...
    if (delayed_work_pending(&fd_timer))
        pr_info("delayed work.function=%p expires=%ld\n",
               fd_timer.work.func,
               fd_timer.timer.expires - jiffies);
    if (delayed_work_pending(&fd_timeout))
        pr_info("timer_function=%p expires=%ld\n",
               fd_timeout.work.func,
               fd_timeout.timer.expires - jiffies);
    pr_info("cont=%p\n", cont);
   ... 
    pr_info("\n");
}

As you can see above, there are a few instances where pr_info() functions are called passing the “%p” format specifier for some function pointers. The issue is that this leaks the address of those function pointers which an attacker can use to calculate the offsets of other, more important pointers, that can later be used to effectively bypass protections like KASLR.

One of the extended format specifiers is the “%fp” which stands for “function pointer” and it ensures that it will not leak a function pointer address which can be used to bypass protections such as KASLR. This is exactly what the patch was to fix this vulnerability.

diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index eae484a..e29d417 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -1819,15 +1819,14 @@ static void show_floppy(void)
    if (work_pending(&floppy_work))
        pr_info("floppy_work.func=%pf\n", floppy_work.func);
    if (delayed_work_pending(&fd_timer))
-       pr_info("delayed work.function=%p expires=%ld\n",
+       pr_info("delayed work.function=%pf expires=%ld\n",
               fd_timer.work.func,
               fd_timer.timer.expires - jiffies);
    if (delayed_work_pending(&fd_timeout))
-       pr_info("timer_function=%p expires=%ld\n",
+       pr_info("timer_function=%pf expires=%ld\n",
               fd_timeout.work.func,
               fd_timeout.timer.expires - jiffies);

-   pr_info("cont=%p\n", cont);
    pr_info("current_req=%p\n", current_req);
    pr_info("command_status=%d\n", command_status);
    pr_info("\n");

Written by xorl

March 18, 2018 at 16:54

Posted in linux

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s