IAIK/sweb

Integer overflow in Loader::loadPage()

Closed this issue · 1 comments

The p_filesz field of an ELF program header entry can be set to a very large number (close to SIZE_MAX), causing an integer overflow when adding it to p_vaddr when data is loaded from the binary. The values of p_vaddr and p_filesz can be chosen by the attacker in a way that the resulting address after the overflow lies within the same page, which passes the checks p_vaddr < virt_page_end_addr and p_vaddr + p_filesz > virt_page_start_addr. An overflow occurs again when calculating the number of bytes to load from the file, causing bytes_to_load to be set to the attacker controlled p_filesz.

Impact: Attacker can write arbitrary data to the ident mapping (consecutive physical pages after the one allocated for loading data from the binary)

Proof of Concept:

  // Attacker controlled data (make sure vaddr + filesz points into the same page)
  pointer test_vaddr = virt_page_start_addr + 0xFF; 
  uint64 test_filesz = 0xFFFFFFFFFFFFFFF0;

    if(test_vaddr < virt_page_end_addr)
    {
      if(test_vaddr + test_filesz > virt_page_start_addr)
      {
        const pointer  virt_start_addr = ustl::max(virt_page_start_addr, test_vaddr);
        const size_t   virt_offs_on_page = virt_start_addr - virt_page_start_addr;
        const l_off_t  bin_start_addr = (*it).p_offset + (virt_start_addr - test_vaddr);
        const size_t   bytes_to_load = ustl::min(virt_page_end_addr, test_vaddr + test_filesz) - virt_start_addr;

        debug(LOADER, "PoC integer overflow, vaddr: %zx, filesz: %zx, bytes_to_load: %zx\n", test_vaddr, test_filesz, bytes_to_load);
        assert(bytes_to_load <= PAGE_SIZE);
      }
    }

this is not a pitfall for students, right?

improving sweb security is part of the exercises and thus shouldn't generally be part of the baseline sweb