Re: [x86.git#mm] stack protector fixes, vmsplice exploit

From: Ingo Molnar
Date: Thu Feb 14 2008 - 15:26:16 EST



* pageexec@xxxxxxxxxxx <pageexec@xxxxxxxxxxx> wrote:

> really, the best defense is to reduce the useful lifetime of any
> leaked canary, and you can't get better than syscall granularity
> without disproportional effort and impact elsewhere (and i'm sure some
> would find even this disproportional ;).

hm, i think per syscall canaries are really expensive.

The per function call overhead from stackprotector is already pretty
serious IMO, but at least that's something that GCC _could_ be doing
(much) smarter (why doesnt it jne forward out to __check_stk_failure,
instead of generating 4 instructions, one of them a default-mispredicted
branch instruction??), so that overhead could in theory be something
like 4 fall-through instructions per function, instead of the current 6.

Also, even with -fstack-protector-all, gcc could detect the _provably_
correct and overflow-safe functions and skip their annotation
altogether. And those are the ones that hurt most: the small and
straightforward (and also, most of the time, overflow-free) ones.

The heuristics for -fstack-protector were really botched, as you noted
they happened to mark vmsplice as "safe". So either we do the full thing
or nothing - anything inbetween is just russian roulette and false sense
of security.

But per syscall canary randomization is something that would be a drag
on our null syscall latency forever. I'm really unsure about it. It will
also be driven in the wrong direction: people would try to "optimize"
the per syscall random number generation which is a constant erosive
force on its strength and there's no strong counter-force. (and no clear
boundary either 'random32 should be plenty enough' is too vague as
limit.)

So lets perhaps also analyze the security effects of not having per
system call canaries and make the best out of it: the main threat is
information leaks via padding and similar initialization mistakes [which
have almost zero accidental discovery rate], right?

So could we perhaps somehow turn kernel-space information leaks into
functional, and hence detectable failures? Wouldnt for example kmemcheck
notice them, once they are copied to user-space? [ If you havent seen
kmemcheck yet i think you'll love it, it's a similarly neat trick as the
pte noexec trick you did in the PaX kernel. It's similarly disgusting as
well ;-) ]

> > TODO: perhaps all vsyscall functions need to move into separate .o
> > files. (probably academic as the functions affected by that tend to
> > be very simple and do not deal with anything overflowable.)
>
> yeah, i wasn't suggesting it for its security value, more like for
> 'full coverage'. if such a separation isn't useful otherwise (no idea
> if not having the .vsyscall* code along with related kernel code would
> be confusing for the reader for example), i'd say this isn't
> important.

perhaps it would be more useful to have some "no stack protector" gcc
attribute. We could then stick that into the __vsyscall definition and
it's all done and self-maintaining from that point on. (because a
missing __vsyscall annotation results in a runtime failure.) (I'd fully
expect GCC to not have provided such an attribute.)

but yes, i agree in general that it's easier to maintain something if
it's full coverage, that way one does not have to keep in mind (and
cannot accidentally forget ;-) the exceptions.

Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/