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