I've been reading more about security lately, and one thing I don't understand is how buffer overflows allow for true RCE these days. I believe all modern processors support having non-executable pages; why is any program-writeable page executable? Especially in C, where there's no JIT. It also seems like address space randomization would make RCE pretty hard.
Obviously they can still arbitrarily write the instruction pointer, which is very bad and possibly bootstrappable into fully RCE, but I still see more conventional RCE described in recent books and wonder if and why it's still doable.