CHERIoT-Platform / cheriot-rtos

The RTOS components for the CHERIoT research platform

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compiler / switcher does not validate non-software-visible pointers

davidchisnall opened this issue · comments

There are two important pointers held in registers that may introduce attack vectors:

  • If a function takes more arguments than fit in 6 registers, ct0 contains a pointer to stack space.
  • If a function returns a structure that does not fit in registers, ca0 contains caller stack space to store the result.

Both of these should have RWlgm permissions and be sufficiently large that they can hold the values that the compiler expects. None of the code in the RTOS currently uses this part of the ABI, but before we can the compiler should be fixed so that it checks these on entry and returns -1 if the checks fail. The checks should be:

  • The address equals the base.
  • The bounds are at least the compiler expected size.
  • The base is greater than the address of csp[1] on entry.
  • The permissions are at least the set listed above. This includes a check for store-local, which guarantees that this is part of our stack.

The sequence is likely to look something like:

  # Check that address equals base
  cgetaddr t1, ca0
  cgetbase t2, ca0
  bne      t1, t2, fail
  # Check that base is greater than or equal to stack pointer on entry
  blt      t2, sp, fail
  cgetlen  t1, ca0
  li       t2, {expected size}
  blt      t1, t2, fail
  cgetperm t1, ca0
  li       t2, 0x7a
  bne      t1, t2, fail
  # Rest of prolog
  ...


fail:
  li a0, -1
  li a1, -1
  cret

This is quite a long sequence (and will be effectively double this length for functions that both return structures and take on-stack arguments), so we might consider outlining it if it proves to increase code size.

[1] This is a bit fun because compartment entry points may be called from within the compartment and so we don't want to check that it's out of range of CSP.