Post by Rainer Weikusat Post by Noob Post by Noob
And perhaps VS by default inserts code to write to every
stack page when allocating more stack? (Which is sure to
trigger a fault when trying to jump over the guard pages)
That's the 'stack probe' technique, which
says it has been doing since XP.
It seems there needs to be some "cooperation" between
user-space and kernel to guard against the class of
vulns under discussion.
Why didn't you make that "It seems there needs to be some coop bet uspac
and kern to guard ag the class of vulns un disc"? I mean, use of
polysyllables is clearly un-american as nobody has that much time on his
hands! [I mean, use of pols is clear un- as nob ...]
[Sorry for the OT-remark but I *hate* this language mutilation by "I
can't be arsed!"-people]
Post by Noob
Kernel needs to enforce a "no tresspassing" gap
between stack and heap. (BTW, "the" stack is often
mentioned, but doesn't every thread get a stack?)
And user-space needs to make sure it will not jump
over the gap. Perhaps VS enforces that for the code
it compiles, but code compiled with mingw would have
the same vuln than on Linux, right?
The vulnerability (vulnerabilities, actually) under discussion is that
various programs copy an arbitrary amount of data from untrusted sources
onto the stack despite running with elevated privileges.
Some languages like C++ and Rust boast about how well (and how seamlessly)
they do dynamic allocation on the stack. AFAIU Rust will even try to
allocate closures and (soon) coroutines on the stack. (Given Rust's
ownership semantics, it's burdensome to write code that doesn't also happen
to lend itself to a stack-like, LIFO-ordered allocation pattern.)
Post by Rainer Weikusat
The solution to this is to fix the code, not come up with yet another
bizarre exploit mitigation scheme ...
The correct solution is compiler stack probes, pure and simple. In terms of
code injection it's not a mitigation, but a complete solution. There's no
contention on this point. (It's worth pointing out that PATH_MAX on Linux is
4096, the size of a VM page on both the x86 and amd64 architectures.) The
maintainers of both GCC and LLVM have had this on their TODO list for a long
while, but it was low priority. This is one of those instances where an
obvious security issue was left unattended because people tend to think that
because they find it difficult to construct a realistic exploit, then others
must find it equally difficult.
I'm surprised stack probes hadn't been implemented yet. The last few times
I've counciled a C programmer not to use VLAs or alloca(), especially for
user-tainted data, I qualified the advice with the observation that stack
probes constrained the issue to merely segfaulting on malicious (or
maliciously stupid) input. I thought stack probes had been implemented a few
years ago as part of the support for segmented stacks (for Go on GCC and
Rust on LLVM). But apparently in both cases that stack probe work was
specific to the segmented stack support and not implemented in a more
The Rust team especially has egg on its face. When they moved away from
segmented stacks they appear to have _known_ that they were losing stack
probes. Rust makes hay about it's cost-free, guaranteed memory safety, as
well as it's robust use of stack allocation.
 Even a well-written component--e.g. a ftw(3) implementation--that
recursively walks a directory tree could be vulnerable. Or even code that
doesn't recurse but is merely invoked from a language like Rust or C++ that
heavily relies on stack allocation. IME, excessive use of dynamic allocation
in C often leads to bugs and exploits. GNU project code is notorious for its
complexity, and IMO part of that is the GNU style manual rule that there
should never be arbitrary size limits, which results in implementations that
rely on dynamic allocation for every non-integral object. Arbitrary limits
are great simplifiers. Arbitrary limits make stack allocation more natural
and more defensible, even in a language like C.