3

Why don't processors have separate stack registers for CODE and DATA?

This would make it almost impossible to alter the flow of control of the program by overwriting the stack with a local stack buffer overflow, changing the original return address of the function.

Sure some languages don't differentiate between CODE and DATA (to the programmer, conceptually, but internally they do).

Walt Howard
  • 7,676
  • 1
  • 16
  • 11
  • 1
    You could implement that without any explicit assistance from hardware – harold Feb 17 '16 at 19:29
  • Do you mean a second stack for the return address? If so, the PIC18 microcontroller have a 32-entry hardware stack for return addresses. – fsasm Feb 18 '16 at 22:59
  • Unfortunately, some languages do allow non-differentiation between CODE and DATA - think C/C++ function pointers, vtables, etc. If you can redirect a jump, that target becomes a gadget in [ROP](https://en.wikipedia.org/wiki/Return-oriented_programming). – rwong Oct 28 '16 at 03:16
  • Another thing is, both stack pointers will need to be protected; code that can potentially manipulate these pointers directly will need to be verified that they don't modify them into an invalid state that allows jailbreak. – rwong Oct 28 '16 at 03:18

1 Answers1

1

Short answer

Using multiple stacks is not compatible with legacy software and hardware.

Detailed answer

The paper Defending Embedded Systems Against Control Flow Attacks (published in 2009) proposes using multiple stacks. The abstract says:

This paper presents a control flow enforcement technique based on an Instruction Based Memory Access Control (IBMAC) implemented in hardware. It is specifically designed to protect low-cost embedded systems against malicious manipulation of their control flow as well as preventing accidental stack overflows. This is achieved by using a simple hardware modification to divide the stack in a data and a control flow stack (or return stack).

You can see the paper for the details of how their system is implemented.

As to the question of why this (or a similar) technique has not already been adopted, the introduction of the paper gives some hints (emphasis added):

Given the high impact that control flow attacks had on commodity systems, many countermeasure techniques have been proposed to defend against such attacks, such as: binary randomisation [14], memory layout randomisation [20, 21], stack canaries [9], tainting of suspect data [19] enforcing pages to be writable or executable [3, 21], Control Flow Integrity enforcement [1]. However, most of those countermeasures are demanding in terms of computation capabilities, memory usage and often rely on hardware that is unavailable to simple micro-controllers such as a Memory Management Unit (MMU) or execution rings. Moreover, they mostly use software solutions as hardware modifications (for example on the IA-32 architecture) are difficult and likely to cause problems with legacy applications.

Basically a system that uses multiple stacks is not compatible with legacy hardware and/or software. It is very difficult to make this sort of change for general purpose computing where legacy code needs to be supported.

Instead a large number of other possible solutions have been proposed and implemented that help mitigate security vulnerabilities associated with stack overflow.

Gabriel Southern
  • 9,602
  • 12
  • 56
  • 95