And only provided that the system in question allows execution of any
code that's on the "local stack",
False. Stack-smashing attacks which exploit implementations with
non-executable stacks are well-documented. See so-called "return
into libc" exploits, for example.
I'll list here just a few of the very popular processors/processor lines
which would allow such data/code separation in a sensible manner:
- Most of harvard-like architectures (so, a lot of RISC processors);
But not the POWER family, which is the most popular RISC processor
for general-purpose computing (thanks to Apple). The POWER MMU lacks
separate read and execute page-protection bits.
- The 68k processors, back to the 68000 (albeit a bit crude on this);
- The x86 series, back to the 286 (with the ability of marking memory
segments as executable or not);
But not pages, so this facility is useless for the dominant x86 OSes.
The merits of separate I&D have been debated endlessly in any number
of places. This is not the forum to bring them up again. Try
alt.folklore.computers or comp.arch. They're probably sick of it
too, but at least it's on-topic there.
But we're getting a bit off-topic. Sorry.
Entirely off-topic. The effects of Undefined Behavior are OT for
comp.lang.c. Regardless of the value of "a good understanding of the
underlying reality", not every topic related to programming belongs
here. Further, what you refer to as "underlying reality" is not the
same for all C implementations. Are you prepared to discuss how
every conforming implementation deals with Undefined Behavior caused
by overwriting an automatic variable?