3

How a simple Linux kernel memory corruption bug can lead to complete system comp...

 2 years ago
source link: https://lwn.net/Articles/873410/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

[Posted October 20, 2021 by jake]

Over at the Project Zero blog, Jann Horn has a lengthy post on a kernel bug, ways to exploit it, and various ideas on mitigation. While the exploitation analysis is highly detailed, more than half of the post looks at various defenses to this kind of bug.

This blog post describes a straightforward Linux kernel locking bug and how I exploited it against Debian Buster's 4.19.0-13-amd64 kernel. Based on that, it explores options for security mitigations that could prevent or hinder exploitation of issues similar to this one.

I hope that stepping through such an exploit and sharing this compiled knowledge with the wider security community can help with reasoning about the relative utility of various mitigation approaches.

A lot of the individual exploitation techniques and mitigation options that I am describing here aren't novel. However, I believe that there is value in writing them up together to show how various mitigations interact with a fairly normal use-after-free exploit.


(Log in to post comments)

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

Posted Oct 20, 2021 19:13 UTC (Wed) by petkan (subscriber, #54713) [Link]

This is a lengthy post indeed, one that touches a whole bunch of valid points. Good job. However, like a friend of mine once said, don't hire idiots to write code. May not be entirely relevant in this case, but i like the phrase a lot.

Locking one thing while modifying another is a classic mistake. While i do agree that compiler extensions could (and do help) i also insist that staring carefully at your code also produce great results. C is a very sharp tool and proper care must be taken when using it. You can't just absent-mindedly wave around with a rather sharp sword, can you? ;)

I naively wish people contemplate a bit more and hurry a bit less...

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

Posted Oct 20, 2021 19:58 UTC (Wed) by JoeBuck (subscriber, #2330) [Link]

That code wasn't written by an idiot, but rather by a very smart human being who messed up, and the bug was missed by many other very smart human beings. But many bugs look stupid when you finally locate them.

A regular experience many of us have: "who wrote this stupidity?" ... checks the history ... "oops, it was me!"

Starting carefully at your code will find some issues, but others will slip through.

Locking one thing while modifying another

Posted Oct 20, 2021 20:13 UTC (Wed) by tialaramex (subscriber, #21167) [Link]

This is also, perhaps surprisingly to people who haven't dabbled in it, one of the things Rust already uses ownership tracking to solve.

Rust's Mutex type (obviously not suitable for the kernel, but this reflects the approach you'd use) has a lock() method and that's how you get the thing protected by the Mutex. let mut foo = foo_lock.lock().unwrap(); gives you foo, the thing locked by foo_lock, if you meant to lock bar instead of foo, well, you've got foo here, there is no bar variable, to get that you need to let bar = bar_lock.lock().unwrap() instead or as well.

[ If you wonder, how do I *unlock* the Mutex then, the answer is you just get rid of the locked data the lock is protecting, this would happen as soon as the variable foo goes out of scope of course but if for any reason that's not soon enough, just call drop(foo) and since foo was moved into the empty function it's gone and the unlock happens immediately, if you feel the need for a more self-documenting way to write this, Nightly Rust provides unlock() which takes your data foo and drops it for you ]

Obviously Rust type magic can't cure pure logic errors. If the problem was that the code locks and modifies some totally unrelated tty, that might still be a grave Linux bug, but this type of bug where the wrong thing was locked but the right thing was modified (or vice versa) is avoided in Rust.

Locking one thing while modifying another

Posted Oct 20, 2021 22:24 UTC (Wed) by roc (subscriber, #30627) [Link]

FWIW there's a lot we could say about using the Rust type system to avoid pure logic bugs, even though we can't eliminate them. E.g.:
* Use newtypes to avoid confusing values in different units
* Use enums like Result<T,E> to eliminate the use of "magic values" (e.g. -1 for error) which you inevitably forget to check for in some places
* Give distinct states of a value different types and transition between those states using methods that consume 'self', so you can never call a method with the value in the wrong state

Just saying this because "Rust is great for memory safety but doesn't help with logic errors" is a bit of a meme and the latter part is not true.

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

Posted Oct 20, 2021 20:25 UTC (Wed) by rahulsundaram (subscriber, #21946) [Link]

> However, like a friend of mine once said, don't hire idiots to write code

We can either continue to engage in this kind of unproductive finger wagging and continue to see a steady stream of security issues or figure out a better way to handle the development that allows imperfect developers and reviewers (which happens to be almost all of them) to work with core infrastructure code in a more secure fashion.

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

Posted Oct 20, 2021 20:47 UTC (Wed) by mpr22 (subscriber, #60784) [Link]

> don't hire idiots to write code

Who never made a mistake, made nothing.

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

Posted Oct 20, 2021 22:26 UTC (Wed) by roc (subscriber, #30627) [Link]

This is trolling, surely. If so, well done.

Otherwise ... if you only hire people who never make mistakes like this, you would never hire anyone, not even yourself.

How a simple Linux kernel memory corruption bug can lead to complete system compromise (Project Zero)

Posted Oct 21, 2021 0:00 UTC (Thu) by motk (subscriber, #51120) [Link]

This isn't helpful.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK