
Linux 3.4+: arbitrary write with CONFIG_X86_X32 (CVE-2014-0038) - akerl_
http://seclists.org/oss-sec/2014/q1/187
======
barrkel
This might be useful context:

[http://en.wikipedia.org/wiki/X32_ABI](http://en.wikipedia.org/wiki/X32_ABI)

 _an application binary interface project for Linux that allows programs to
take advantage of the benefits of x86-64 (larger number of CPU registers,
better floating-point performance, ... ) while using 32-bit pointers and thus
avoiding the overhead of 64-bit pointers_

~~~
userbinator
So in other words, it's a 32-bit address space in 64-bit mode? I thought that
wasn't possible with x86-64... in fact the biggest mistake I think with
x86-64, after some(admittedly not much) reading of the manuals is that it
wasn't like the 16/32-bit where you could independently choose the default
operand and address sizes, and use 32-bit addresses or registers in 16-bit
mode and vice-versa.

~~~
nknighthb
Not sure what you were reading, but to the best of my knowledge, long mode
retains almost all of the 32-bit instructions, only a relative handful were
ripped out.

Code running in 32-bit protected mode can't access 64-bit instructions or
registers, of course, but that's a different issue. x32 is basically just long
mode code that limits itself to instructions that use 32-bit addresses.

~~~
pbsd
You can jump between 32-bit and 64-bit modes in a 64-bit Windows and Linux by
switching between the 0x23 and 0x33 code segments. Like so:

    
    
        BITS 32
        start:
            call far 0x33:code64
        code32:
            nop ; resume
        code64:
        BITS 64
            xor rax, rax
        BITS 32
            retf ; return to 0x23:code32

~~~
0x0
That's interesting that the CS values are the same in windows and linux, more
than a coincidence... Is this part of some x86_64 ABI spec?

~~~
pbsd
After checking the docs, it seems the fast syscall instructions force the GDT
to be laid out in a specific order. Since the segment values (selectors) are
really offsets into the GDT, it makes sense that they end up being the same.

------
lelf

        -       if (get_compat_timespec(&ktspec, timeout))
        +       if (compat_get_timespec(&ktspec, timeout))
                        return -EFAULT;
    

Sigh

------
saintdev
On the plus side, hardly anybody uses x32 ABI.

~~~
akerl_
Unfortunately, it looks like Ubuntu just recently enabled it in their kernels:

[https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1274754](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1274754)

~~~
vinkelhake
How do you get an x32 Ubuntu? I couldn't find it on the regular download page.
I'm not surprised since it _is_ a rather obscure configuration.

~~~
akerl_
I don't run Ubuntu myself, but CONFIG_X86_X32 isn't a new architecture, it's
an option for 64 bit kernels. Based on the state of that bug report, it looks
like it's an option they've enabled in their recent 64 bit kernels (Quantal+)

~~~
ahomescu1
You need a completely different userland, compiled for x32 instead of amd64.
Just running the default amd64 installation with a x32 kernel doesn't make it
x32. EDIT: It would also work for just running x32 apps on an amd64 system,
but then you only get the x32 benefits for those applications.

~~~
mnw21cam
You don't need a whole x32 userland in order to be exploited. Just a single
x32 binary executable that happens to not depend on on any external libraries.

~~~
spendergrsec
You don't even need that. This can be done within a 64bit process using the
x32 syscall number for recvmmsg.

-Brad

~~~
mnw21cam
Ouch.

------
jlgaddis
While we sometimes get laughed at for not running the latest and greatest, I
am (once again) quite glad that I'm running RHEL 5 and 6 and their 2.6.18 and
2.6.32 kernels.

~~~
jasonzemos
Those are patched against the myriad of bugs and vulnerabilities from _the
last 8 years_... haha?

~~~
zorked
As long as he's upgrading, yes they are, Red Hat fully supports those kernels.

------
jjjeffrey
At the bottom there are two lines that taken together really confuse me:

    
    
        <grsecurity> If you're running Linux 3.4 or newer and enabled CONFIG_X86_X32 , you need to disable it or update 
        immediately; upstream vuln CVE-2014-0038
    

and

    
    
        <grsecurity> In case there's confusion, this vuln is not about 32bit userland on 64bit (CONFIG_X86_32), but the new X32 
        ABI.  Ubuntu enables it recently
    

Does the second line affect the first? EDIT: I ask because it looks like I
need to fix my kernel, but I'd rather be lazy if possible.

~~~
elwin
CONFIG_X86_X32 and CONFIG_X86_32 are different.

The first one, with the second X, enables the new X32 ABI. The second one,
without the second X, is the "32bit userland on 64bit".

------
akerl_
Has anyone seen talk of this leading to an expedited 3.13.2/3.12.10 release?
If I need to manually patch my kernels to fix this, I'll do it, but if
upstream is going to release fixed versions shortly, that seems like the
preferable solution.

So far though, I haven't seen anything about merging in the patch provided by
PaX.

~~~
nknighthb
Are you actually using x32? I doubt most people are. It didn't even exist in a
stable kernel until April 2012.

~~~
akerl_
I am not actively using it, but I am running kernels that have CONFIG_X86_X32
enabled.

~~~
nknighthb
Yeah, I just saw that Ubuntu at least already enabled it quite a while ago.
Ouch.

~~~
akerl_
I don't suppose there's some way to disable x32 from within a running system
that's not using it?

edit: It doesn't appear there is. Not shocking, but I was hoping for a bit of
luck.

~~~
nknighthb
As far as I know, no. I'm about 90% sure you have to rebuild the kernel to
disable it. That said, I've only read about it, not played with it, and I
don't have a box with it enabled at my fingertips.

That said, this is a local exploit, so unless you have untrusted users or
otherwise run untrusted native code, your risk is pretty low. Someone would
have to exploit something else first to get access to run custom code on the
box.

------
ye
Am I the only one shocked by the lack of comments in the code? It's literally
a wall of code.

~~~
barrkel
How familiar are you with largish C codebases?

At this level, you're dealing with an API at the calling end (you should be
fairly intimately familiar with the semantics without much reference to the
docs if you're working on the implementation) and the functions being calling
are almost readable as English.

Code should strive to be written such that it doesn't need comments unless
it's being clever - and it should avoid being clever if possible.

Also, I'm not sure where you saw a "wall of code". I don't see any walls of
code, not in the commit diff, nor in the smaller diff in the email. A wall of
code, for me, would have to be long (say, 70+ lines - but it depends on the
language) and dense (e.g. boolean expressions complex enough to need
parentheses to clarify precedence).

~~~
grannyg00se
I'm reading Clean Code (again). I dont see that code as being particularly
bad. But it definitely wouldnt follow the axioms in that highly regarded book.
I realize it isnt java but can someone familiar with the text comment on the
number of parameters in that function and the naming of some of those
variables?

Relevant quote: "The ideal number of arguments for a function is zero
(niladic). Next comes one (monadic), followed closely by two (dyadic). Three
arguments (triadic) should be avoided where possible. More than three
(polyadic) requires very special justiﬁcation—and then shouldn’t be used
anyway."

~~~
mikeash
I find the idea that the ideal function takes no arguments to be astonishing.
There are only two kinds of functions that take no arguments:

1\. Those that return the same result every time.

2\. Those that mutate some internal state (or, roughly equivalently, those
that inspect internal state being mutated elsewhere).

#1 isn't all that useful in general, although there are obviously cases where
it's exactly what you want. For #2, while state is useful at times and a
necessary evil in many other cases, it's hardly ideal.

Even a single parameter seems decidedly un-ideal. To do useful work in
general, you're typically going to want to take two parameters: something to
be modified, and the modification to make. This can be done with state (modify
in place) or functionally (return a new object with the modifications
applied). Once again, having a single argument seems to imply either something
not very useful (basically a getter or some similar derive-a-value function)
or something relying on mutable state. You need two arguments to achieve the
sort of combinatorial power that makes functions interesting and properly
useful.

~~~
andrewaylett
I wonder if the book, which I assume is talking about Java, is ignoring the
implicit zeroth argument which is the object you're invoking the function on.
Obviously in C you have to make that parameter explicit, but I've got enough
experience of both languages to know that people often don't consider the
object to be a parameter to one of its member functions.

So if you're converting that rule back to C, you'd need to add one to each
element of the rule. The one parameter rule is saying that when special cases
are common, a special function to handle it is a good thing. So writing `i++`
rather than `i = i + 1` or `next(node)` rather than `skip(node,1)`.

~~~
mikeash
That would make sense, except for the part where Java doesn't have functions
at all, but rather methods. I imagine you could call them functions, but I
haven't seen it done, and that sort of terminology sloppiness leads exactly to
confusion like this.

~~~
grannyg00se
Thanks for the responses. The text is definitely referring to Java methods as
functions, and not counting the implicit object instance (this) as a
parameter. The text also considers multiple parameters of the same type that
are treated identically as lists counting as one parameter.

~~~
mikeash
Appreciate the clarification. The advice sounds much more sane that way. It
sounds like a terribly confusing way to put it, but maybe it's better in
context.

