It rather involved being on the other side of this airtight hatchway: Passing invalid parameters from kernel mode to another kernel-mode function corrupts the kernel (who knew?)


A customer reported a vulnerability in a kernel function, let's call it kfunc.

The kernel-mode kfunc function doesn't validate any of the pointers passed to it. As a result, you can pass anything you want as the output pointer, and it will blindly try to write to it. If you pass null, you will crash the kernel. Or if you pass a pointer to memory you want to corrupt, you can corrupt an arbitrary 4-byte value.

Maybe I can find a way to pass an invalid parameter from user space all the way down to the kfunc function.

Please contact us soon regarding this issue!

Okay, first things first. In the first paragraph, there is no elevation. The kernel-mode kfunc function is callable only from kernel mode. The caller is in kernel mode, and it is tricking a kernel mode function into writing to an arbitrary memory location. But so what? The caller could just save itself the trouble of using kfunc as the middle man and just corrupt the memory directly. In other words, instead of

void attack_the_kfunc()
{
 kfunc(crazy_pointer_value);
}

you can just do

void attack_the_kfunc()
{
 *crazy_pointer_value = 42;
}

This is even more powerful, because not only do you get to corrupt the memory at crazy_pointer_value, you even get to pick what value to corrupt it with!

Now, if there were a way to call the kfunc function with parameters controlled by user mode, then you would be onto something.

Which leads us to the next paragraph, which boils down to "Maybe there is a way to call the kfunc function with parameters controlled by user mode." In other words, the second paragraph says, "Maybe I can find a vulnerability."

Yeah, maybe you can find a vulnerability. Let us know if you do.

But so far, you haven't found a vulnerability. All you've said is "Maybe there is somebody who is doing a bad thing."

"Industrial paper-cutting machines are dangerous and expensive. We keep the paper-cutting machine in a special room, and only people who have gone through training are allowed in the room. Maybe there is a way to get somebody who has access to the special room to put an unauthorized object in the paper-cutting machine and damage it."

Yeah, maybe. If you find such a person, let us know. Because they're in a lot of trouble.

Comments (22)
  1. Antonio Rodríguez says:

    The paper cutting machine example lacks one point. They aren’t sending the report to the building’s security guard, but to the paper cutting machine’s maker.

  2. Joshua says:

    I find it hard to believe that programmers believe that there’s any such thing as security against code loaded into kernel.

    1. Zan Lynx' says:

      It would depend on the type of kernel. Micro-kernel designs are supposed to be secure against code in other kernel services.

      You should not be able to pass a message between micro-kernel services that will cause bad behavior, just as making a REST call to a web API should not be able to corrupt a database or return unauthorized data.

      1. This wasn’t a message-pass. Just a straight function call.

      2. Joshua says:

        They’re not. They’re hardened against accident not against somebody intentionally issuing bad DMA requests or other nasties.

        1. Patrick says:

          They are (or atleast can be) with IOMMU.

          1. Joshua says:

            Microkernels fell out of favor before IOMMU ever existed. Even so, any device that requires an interrupt handler is going to require a device driver that can cause you a lot of trouble.

  3. user says:

    With these articles, I’m always curious to know how the engineering team responded. Did they say “thanks, we’ll look into it” with no more follow up, or “thanks, but this is not a vulnerability” which I imagine would lead to a long exchange arguing about whether it is a real vulnerability, or maybe no response at all?

    1. Rick C says:

      Who knows what they said to the reporter, although Raymond has repeatedly said that every report is investigated, just in case.

  4. Giedrius says:

    But that does not follow defense in depth philosophy.
    Like internet explorer runs (or used to run) with low rights just because it’s assumed it will be exploited sooner or later. Why don’t apply the same rules to the kernel?

    1. zboot says:

      This doesn’t make sense. How can the kernel run with “low rights”?

      1. Permish N. Deenide says:

        x86 has 4 protection levels, ring 3 is typical user-mode, and kernel-mode runs in ring 0, but part of the kernel could be in ring 1, so it would have “low rights”.

        1. alegr1 says:

          x64 only has 2

          1. Klimax says:

            Incorrect. It has 4. Chapter 5.5 of System programming Guide has no mention about any such limitation.

      2. Patrick says:

        Apart from rings (which NT doesn’t use, because it would screw up portability), there’s also the option of using a hypervisor.
        Which is in fact used to make the kernel less-than-omnipotent in recent Windows. See Credentials Guard, Virtualization-Based Security, etc. All these are about making sure there are things even the kernel can’t do.

  5. Erik F says:

    I’m sure that people would love running what would essentially be the checked build. Given the backlash when security fixes degrade performance, I can confidently predict that there would be no negative reactions to this! :-)

  6. Billy O'Neal says:

    This code example criminally doesn’t call the exploit function pwnz0r :)

  7. MV says:

    I’m wondering what sort of pointer validation they expect. I suppose the function could check for nulls (though I’m not sure what it should do if it finds one – maybe crash the kernel? Oh wait…), but how is it supposed to differentiate between a legit pointer vs a “bad” pointer to memory that will be corrupted?

    1. Torsten Kammer says:

      Simple: The function should get an additional parameter where you pass the source code of the caller, so it can determine whether the pointer is correct and the caller’s intentions are pure.

      1. Erik F says:

        They can crib the implementation from the RFC for the Evil Bit (https://www.ietf.org/rfc/rfc3514.txt). For bonus points, they can add this to all the user-mode interfaces as well to ensure that bad programs don’t bug users as well!

        1. Brian says:

          All the best RFCs come out in early April.

  8. Yuhong Bao says:

    What is fun is bugs that are non-exploitable and only cause a BSoD. With NTVDM being disabled in Win8 by default there are going to be more of them. Some can BSoD a terminal server and kick everyone off. I wonder if you could blog about it.

Comments are closed.

Skip to main content