Skip to content

arch: riscv: userspace: potential security risk when CONFIG_RISCV_GP=y #81372

Closed
@ycsin

Description

@ycsin

Describe the bug

When the Global Pointer (GP) relative addressing is enabled (CONFIG_RISCV_GP=y), the gp reg points at 0x800 bytes past the start of the .sdata section which is then used by the linker to relax accesses to global symbols.

#ifdef CONFIG_RISCV_GP
/*
* RISC-V architecture has 12-bit signed immediate offsets in the
* instructions. If we can put the most commonly accessed globals
* in a special 4K span of memory addressed by the GP register, then
* we can access those values in a single instruction, saving both
* codespace and runtime.
*
* Since these immediate offsets are signed, place gp 0x800 past the
* beginning of .sdata so that we can use both positive and negative
* offsets.
*/
. = ALIGN(8);
PROVIDE (__global_pointer$ = . + 0x800);
#endif

However, the gp reg is not protected against write from userspace, this means that a rogue userspace can corrupt the gp reg, and cause the compiled instruction to access random addresses.

To Reproduce
Steps to reproduce the behavior:

  1. Build the qemu_riscv64 board with userspace and CONFIG_RISCV_GP enabled
  2. Note the value of the gp register
  3. Write some random value to the gp reg from one userspace thread
  4. Notice that the gp reg is now changed

Expected behavior

The gp register should remain a constant.

Impact

A rogue thread can corrupt the gp reg and cause the entire system to hard fault at best, at worst, it can potentially trick the system to access another set of random global symbols.

Environment (please complete the following information):

  • Toolchain (e.g Zephyr SDK, ...): 0.16.8
  • Commit SHA or Version used: v3.7 branch

Metadata

Metadata

Labels

area: RISCVRISCV Architecture (32-bit & 64-bit)area: SecuritySecuritybugThe issue is a bug, or the PR is fixing a bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions