Re: [RFC][PATCH] exec: Use init rlimits for setuid exec

From: Kees Cook
Date: Fri Jul 07 2017 - 01:15:34 EST


On Thu, Jul 6, 2017 at 10:10 PM, Kees Cook <keescook@xxxxxxxxxxxx> wrote:
> On Thu, Jul 6, 2017 at 9:48 PM, Andy Lutomirski <luto@xxxxxxxxxx> wrote:
>> How about a much simpler solution: don't read rlimit at all in
>> copy_strings(), let alone try to enforce it. Instead, just before the
>> point of no return, check how much stack space is already used and, if
>> it's more than an appropriate threshold (e.g. 1/4 of the rlimit),
>> abort. Sure, this adds overhead if we're going to abort, but does
>> that really matter?
>
> We should avoid using up tons of memory and then failing. Better to
> cap it as we use it. Plumbing a sane value into this shouldn't be hard
> at all. Just making this a hardcoded 2MB seems sane (1/4 of 8MB).
>
>> I don't see why using rlimit for layout control makes any sense
>> whatsoever. Is there some historical reason we need that? As far as
>> I can see (on insufficient inspection) is that the kernel is trying to
>> guarantee that, if we have so much arg crap that our remaining stack
>> is less than 128k, then we don't exceed our limit by a little bit.
>
> IIUC, this is a big deal on 32-bit. Unlimited stack triggers top-down
> mmap instead of bottom-up. I mean, I'd be delighted to get rid of
> this, but I thought it was relied on by userspace.

I always say this backwards. :P Default is top-down (allocate at high
addresses and work down toward low). With unlimited stack, allocations
start at low addresses and work up. Here's the results (shown with
randomize_va_space sysctl set to 0):

$ ulimit -s
8192
$ cat /proc/self/maps
08048000-08050000 r-xp 00000000 fc:01 843 /bin/cat
08050000-08051000 r--p 00007000 fc:01 843 /bin/cat
08051000-08052000 rw-p 00008000 fc:01 843 /bin/cat
08052000-08073000 rw-p 00000000 00:00 0 [heap]
b7be7000-b7de7000 r--p 00000000 fc:01 403307 /usr/lib/locale/locale-archive
b7de7000-b7f9a000 r-xp 00000000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
b7f9a000-b7f9b000 ---p 001b3000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
b7f9b000-b7f9d000 r--p 001b3000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
b7f9d000-b7f9e000 rw-p 001b5000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
b7f9e000-b7fa1000 rw-p 00000000 00:00 0
b7fb2000-b7fd7000 rw-p 00000000 00:00 0
b7fd7000-b7fd9000 r--p 00000000 00:00 0 [vvar]
b7fd9000-b7fdb000 r-xp 00000000 00:00 0 [vdso]
b7fdb000-b7ffd000 r-xp 00000000 fc:01 276959 /lib/i386-linux-gnu/ld-2.24.so
b7ffd000-b7ffe000 r--p 002d7000 fc:01 403307 /usr/lib/locale/locale-archive
b7ffe000-b7fff000 r--p 00022000 fc:01 276959 /lib/i386-linux-gnu/ld-2.24.so
b7fff000-b8000000 rw-p 00023000 fc:01 276959 /lib/i386-linux-gnu/ld-2.24.so
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]
$ ulimit -s unlimited
$ cat /proc/self/maps
08048000-08050000 r-xp 00000000 fc:01 843 /bin/cat
08050000-08051000 r--p 00007000 fc:01 843 /bin/cat
08051000-08052000 rw-p 00008000 fc:01 843 /bin/cat
08052000-08073000 rw-p 00000000 00:00 0 [heap]
40000000-40022000 r-xp 00000000 fc:01 276959 /lib/i386-linux-gnu/ld-2.24.so
40022000-40023000 r--p 002d7000 fc:01 403307 /usr/lib/locale/locale-archive
40023000-40024000 r--p 00022000 fc:01 276959 /lib/i386-linux-gnu/ld-2.24.so
40024000-40025000 rw-p 00023000 fc:01 276959 /lib/i386-linux-gnu/ld-2.24.so
40025000-40027000 r--p 00000000 00:00 0 [vvar]
40027000-40029000 r-xp 00000000 00:00 0 [vdso]
40029000-4004e000 rw-p 00000000 00:00 0
4005f000-40212000 r-xp 00000000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
40212000-40213000 ---p 001b3000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
40213000-40215000 r--p 001b3000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
40215000-40216000 rw-p 001b5000 fc:01 276980
/lib/i386-linux-gnu/libc-2.24.so
40216000-40219000 rw-p 00000000 00:00 0
40219000-40419000 r--p 00000000 fc:01 403307 /usr/lib/locale/locale-archive
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]


--
Kees Cook
Pixel Security