Re: binfmts.h MAX_ARG_STRINGS excessive value allows heap spraying

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2017-03-08 at 16:05 -0500, Carlos O'Donell wrote: 
> On 03/08/2017 01:18 PM, Leonard den Ottolander wrote:
> > Note that 128KiB * 4096 arguments still adds up to 512MiB!!!
> > 
> > If you don't feel the limit of 4096 arguments is sufficient please
> > provide us with an example where that limit is insufficient.
> 
> (a) Justification.
> 
> A good design should not unduly limit what users can do without a good
> justification.

The justification is that the excessive value of the MAX_ARG_STRINGS
allows heap spraying on 32 bit processes. Or more precisely, the fact
that the multiplication of MAX_ARG_STRINGS and MAX_ARG_STRLEN being
equal to or larger than the 2^32 allows heap spraying.

> It is my opinion that it is not enough data to say that a kernel build
> is sufficient to justify a limit that will affect all applications.
> 
> Minimally I'd expect you to run with such a kernel patch through an entire
> distro build cycle to see if anything else breaks.

I don't think that's really necessary. We can argue whether that value
should be a bit bigger, but a limit is necessary to disable the very
serious attack vector that heap spraying is. In any binary, not just
setuid ones. It's a jumping board to launch any attack via the heap
sprayed binary.

> What if 4096 is too much? Why not lower?

Well, building that C7 kernel didn't work with 2048, it choked on a make
file with something like a little over 3000 -o options. I chose 4096 as
it was sufficient for what I considered to be one of the heaviest use
cases.

The problem is that the multiplication of MAX_ARG_STRLEN and
MAX_ARG_STRINGS should stay below 4GiB to disable the heap spraying.

This means that if f.e. both MAX_ARG_STRINGS and MAX_ARG_STRLEN are
65536 the multiplication is 4GiB and heap spraying is possible.

Of course an extra value limiting this multiplier could be added
(MAX_ARG_STRSLEN along the lines of MAX_ARG_PAGES) and used in exec.c to
limit the total amount of reserved memory. This would allow for the
multiplication of MAX_ARG_STRINGS and MAX_ARG_STRLEN to go beyond 2^32.

And it would save a lot of memory because even with my conservative
values the amount of memory reserved for options is still 65536 x 4096 =
256MiB.

> You could try using systemtap
> or dtrace and running a distro start to finish and auditing the mean
> values you see (see (c) for a discussion on ensuring the userspace tooling
> remains correct after this change).

I have not been dtracing for, but I've not encountered any issue with
kernels using MAX_ARG_STRLEN 65536 and MAX_ARG_STRINGS 4096 so far
(running a.o. on this desktop).

> (b) Attack vector.
> 
> The privilege escalation in your example is caused by a fault in a
> setuid application.

The orthogonality of attack vectors seems to be lost on many I speak on
the issue. It means that every vector has to be judged individually.

The fact that the binary in the example is setuid is
orthogonal/irrelevant to the fact that the high value of MAX_ARG_STRINGS
combined with memory leaks in executables option parsing allow heap
spraying. The heap spraying in itself is a very serious vector that
allows launching any attack via the sprayed heap whether or not the
involved binary is setuid. 

> Can we impose stricter limits on setuid binaries instead of on all
> binaries?

Because an zero day can also be launched via a heap sprayed non setuid
binary like pkcheck. 

> In glibc for example we do not allow certain environment variables to
> impact the behaviour of setuid binaries e.g. MALLOC_PERTURB_ env var
> is ignored in secure mode for setuid binaries (which might be used
> for similar heap-spraying).

This is all very nice but it did not block the attack described in the
article I linked. Your solution sounds rather convoluted. With a
sensible value for MAX_ARG_STRINGS all this working around the real
issue is unnecessary: The heap will no longer collide into the stack of
any binary that does not sanitize its argument list. 

> (c) What limit is appropriate?
> 
> No limit is appropriate. Users should be able to use all of their system
> resources to accomplish whatever task they need to get done.

Oh the poor user. So you rather leave the user exposed to attacks that
leverage heap spraying than imposing a limit?

The point is that this value (the multiplication of both really) allows
an adversary to launch any attack in his inventory using a heap sprayed
binary. That is not a situation you want to prolong.

Regards,
Leonard.

-- 
mount -t life -o ro /dev/dna /genetic/research



--
To unsubscribe from this list: send the line "unsubscribe linux-api" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux