Linux Kernel Through 4.20.10 Found Vulnerable to Arbitrary Code Execution
coocoor.com
coocoor.com
Also, note that there may not actually be a proof-of-concept exploit yet, beyond a reproducer causing a KASAN splat. When people request a CVE for a use-after-free bug they usually just assume that code execution may be possible. (Exploits can be very creative.)
EDIT: I concede in another comment that privesc without code execution can still be useful, but my original claim that privesc does not imply arbitrary code execution still stands.
Getting privilege escalation by definition means that _you are allowed to do stuff you couldn't_ which in itself is an attack vector.
See line 126-127 and compared to the patch at the bottom of: http://patchwork.ozlabs.org/patch/1042902/
Patch is not yet merged into 5.0.0rc7 either. Whereas it is in linux-next. https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-n...
Update: I expect all of the longterm kernels listed on kernel.org will get a backport.
For a made up example, imagine something allocates a structure with a pointer to a function struct->foo, then frees it, but still holds a reference. Now you call a function which allocates a buffer in the same place and copies your arguments into it. When you make the original code try to call struct->foo again, you can any function you want.
Controlling where the OS allocates an important structure seems very difficult and mistakes would likely result in corrupting unrelated data and a crash later on.
I think most browser exploits are actually use-after-free. Check out how simple they can be: https://www.exploit-db.com/exploits/40946
current->cred->uid = 0;There usually is some risk of the allocator not doing what you expect, e.g. because of intervening mallocs/frees from other threads, which indeed is likely to lead to a crash. However, most exploits don’t need to be 100% reliable anyway. And there are various ways to increase reliability.
Caveat: Not all allocators work this way, and even among the ones that do, each has its unique quirks. However, the basic “first in, first out” behavior is quite common across a multitude of implementations. IIRC, the default Linux allocator (it has three to choose from!) is one of them.
[1] Actually range of allocation sizes. Such allocators will usually have a fixed list of “size classes”, which are just specific allocation sizes they support; allocation requests that fall between size classes will just be rounded up to the next highest one. Large allocations (e.g. 4kb+) are handled with a different path.
Fellow data nerds: here's a snapshot of the vulnerability root cause trends for Microsoft Remote Code Execution (RCE) CVEs, 2006 through 2017. A few callouts: heap corruption, type confusion, and uninit increased in 2017. Use after free steady y/y but proportionally declined. https://twitter.com/epakskape/status/984481101937651713
https://github.com/torvalds/linux/commit/9060cb719e61b685ec0...
https://www.kernel.org/doc/html/v4.10/process/coding-style.h...
Mandatory bracing is a step towards more uniformity, and makes additional statements in a conditional block always safe, and at the cost of just one extra line in the code.
It also makes your commits just a little bit smaller; if you do add more lines to a conditional block that was previously braceless, now you just get the new lines in the diff, instead of new lines + opening brace + closing brace.
Cowboy coding of course scoffs at all this and people have different values when making tradeoffs between readability and concision, but there are good reasons for enforcing mandatory braces.
Would you ditch switch-cases in favor of if-else chains (leaving aside fallthrough/Duff's/etc for a moment) because the latter is uniform with existing constructs? Would you ditch "for (int i = 0; ..." in favor of "int i; for (i = 0; ..."?
No. You're talking about applying style rules for if-else conditionals to statements which aren't if-else, which isn't what I was talking about.
This is why the Linux kernel style guide, OpenBSD style, PSR, etc. all have separate guidelines for switch-case along with guidelines for mandatory bracing in if-else.
> Would you ditch "for (int i = 0; ..." in favor of "int i; for (i = 0; ..."?
There isn't a clear-cut rule about this convention in style guides. That's probably in part because the behavior in your two examples is different: in the first case (in C++), i only exists within the scope of the for loop, whereas in the latter case it will continue to exist outside the scope of the for loop.
Whichever one is appropriate would probably depend on context that's outside the scope of a style guide. They're called style guides, after all, not Programming Rules of Law. :-)
https://developers.redhat.com/blog/2016/02/26/gcc-6-wmislead...
I REALLY do not like just calling something correct because it was in the K&R book.
> Also, note that this brace-placement also minimizes the number of empty (or almost empty) lines, without any loss of readability. Thus, as the supply of new-lines on your screen is not a renewable resource (think 25-line terminal screens here), you have more empty lines to put comments on.
Is that really an acceptable justification in the era of cheap 4K displays?
The statement you quoted is simply saying that the author agrees with K&R. Nothing wrong with it.
Keeping line count down help readability. Some people use high resolution with small fonts but that makes my eyes hurt so my terminal has 45 lines when maximized.
in organizational code that will be looked at by dozens of people potentially over decades, no
if (something); { do_something(); }
if (something) {}; { do_something(); }
But, the question is the empty bracket correct or should the contents of the subsequent scope be cut into the scope of the if bracket or copied into it or should the if condition be removed altogether? Code styles do not change the intent and always requiring {} after an if is unnecessary for single statements given the intent is correct:
if (side_effect()); else { do_something(); }
Alternative syntax styles for the same semantics do not clarify the intent of a program.
That's not the job of the linter, that's the job of the engineer.
> The linter could be satisfied by changing the code syntax [...]
What you're suggesting is the equivalent of turning your car stereo up so that you don't hear the strange noise your car is making.
> But, the question is the empty bracket correct or should the contents of the subsequent scope be cut into the scope of the if bracket?
That's the job of the engineer to figure out. The linter is only supposed to raise the flag, not come up with the answer.
if(something);
{
do_something();
} if (a)
b;
c;
So, the brace style really doesn't matter when it comes to tools catching mistakes. If you turn on the warnings and linters, they'll catch all the common bracing errors. If you don't, most of the suggestions here don't really help much.Of course it depends on your configuration, but my organization occasionally uses code blocks to denote things like critical sections in baremetal applications. So you'd have
DINT;
{
// code that should not be interrupted
}
EINT;
I would expect a linter to call out a conditional with no code block, but our workflow is such that we've usually tested things (at least in a manual testing capacity) prior to running any static analysis, so I don't know for sure.(The caveat being, of course, that the linter is only a helper tool - "linter doesn't complain" doesn't guarantee correctness, just that "linter complains" is a fairly certain sign of incorrectness)
sock->sk = NULL;
The curly braces were added as well because the single statement "if" turned into a two statement block. if (something)
doThis();
andThat();
which is absolutely absurd to pass even basic code review. Even most compilers (clang, GCC, etc.) will warn you about that.What omitting curly braces after `if` statements does do is make code ~1% more readable, which can have massive cumulative positive results in security and stability with a multi-million line codebase.
Personally, I think as a regular user of a PC, it's the remote exploits that you really need to worry about, the ones of the form "connect to the Internet and get pwned without doing anything else", fortunately quite rare; and in this era of user-hostile devices, local privilege escalation can even be friendly in terms of rooting and jailbreaks.
No, DOS has no protection against exploits, because by design it has no concept of different privileges. Anyone with access to a DOS system is automatically root and can do anything. "No exploits" is not a good description of that state of affairs.
https://www.kernel.org/doc/html/v4.11/crypto/userspace-if.ht...
syzkaller.appspot.com should give you an idea how many THOUSANDS of these types of bugs exist in the current ToT kernel
Maybe the answer is to do a daily automated recompilation of the kernel, rebuild of the edge LB and FW images followed by automated, staged rollout and rollback. If we're vulnerable anyway, let's just pick up the fixes from yesterday at least and roll back if things go wrong. That sounds really scary, but doable.
It's trivial to apply yourself, though from https://github.com/torvalds/linux/commit/9060cb719e61b685ec0...
curl https://github.com/torvalds/linux/commit/9060cb719e61b685ec0102574e10337fa5f445ea.patch | git am
(Or `| patch -p1` if you don't have a git checkout of the kernel tree.)The NIST page links to this site, which suggests no exploit is known of as yet:
> Attack Vector (AV): Network
> Attack Complexity (AC): Low
SecurityFocus:
> Remote: No
> Local: Yes
¯\_(ツ)_/¯
Remember when Intel ME bugs started coming out and we all had to go to Hacker News and trade rumors to figure out what was really going on?
https://access.redhat.com/security/cve/cve-2019-8912
The problem is one can only really talk about CVE's within the context of the product, perhaps a global CVE wiki /discussion page that can have edits/discussion would be a useful resource.
Very good, gets right to the point. I'll try to remember this for next time, thank you.
Still could be improved a lot. I was thinking of writing up a "requirements doc" at some point for what exactly I think would be useful for such things. I'm not sure I'd be so happy with a Wiki, unless it was curated by trusted people. I wouldn't want (for example) malicious people editing a serious report to say it's no big deal just to buy themselves more time to exfiltrate more data.
But this CVE doesn't appear to be referenced at the moment.
Moving away from C, which is a good thing on my opinion, would ultimately mean moving away from UNIX, as those OSes have other cultures.
So what we really need, since UNIX based OSes aren't going away that fast, is to tame C.
Solaris already did this with hardware memory tagging when running on SPARC.
On Solaris/SPARC an use-after-free attempt would terminate the process, or in this case trigger a kernel panic.
Google has been pushing for the Kernel Self Protection Project[1].
One of such initiatives is collaboration with ARM for hardware memory tagging on ARM v8.5[2].
Intel had MPX, but apparently it didn't took over and now is scheduled for removal, leaving SPARC and future ARM releases as the only architectures where it is possible to have some hardware control over C memory accesses.
[1] - https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Pr...
[2] - https://community.arm.com/processors/b/blog/posts/arm-a-prof...