iovisor/ubpf

Incorrect boundary check leading to the out-of-bound memory access

pcy190 opened this issue · 1 comments

Details

The bounds_check function does not check whether the address + size overflows. When address is large enough, the result of (char*)addr + size would overflow and bypass the check of ((char*)addr + size) <= ((char*)mem + mem_len)), leading to the ouf-of-bound memory access.

ubpf/vm/ubpf_vm.c

Lines 1176 to 1181 in 7d6da19

if (mem && (addr >= mem && ((char*)addr + size) <= ((char*)mem + mem_len))) {
/* Context access */
return true;
} else if (addr >= stack && ((char*)addr + size) <= ((char*)stack + UBPF_STACK_SIZE)) {
/* Stack access */
return true;

Running the PoC code of ldxdw %r6, [%r3-1] can get the invalid memory access:

==135970==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0xffffffffffffffff (pc 0x55bd7a299153 bp 0xffffffffffffffff sp 0x7fff2badf2c0 T135970)
==135970==The signal is caused by a READ memory access.
    #0 0x55bd7a299153 in ubpf_mem_load /ubpf/vm/ubpf_vm.c
    #1 0x55bd7a299153 in ubpf_exec /ubpf/vm/ubpf_vm.c:626:29

Patch suggestion

In the bounds_check function, add the following check:

  if ( ((size_t)addr + size) < (size_t)addr) {
      return false;
  }

Thanks @pcy190, this should now be fixed.