-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Integer Overflow Scan Results
Scanned the following directories for arithmetic operations on usize values that could derive from untrusted guest input:
litebox_shim_linux/src/syscalls/litebox_shim_optee/src/syscalls/litebox_common_linux/src/- All files referencing
PtRegs,esp,rsp,frame_addr, etc.
Good news: signal frame arithmetic is already safe
The core signal delivery code (litebox_shim_linux/src/syscalls/signal/x86.rs and x86_64.rs) correctly uses wrapping_sub/wrapping_add for all arithmetic on guest register values (esp, rsp, frame_addr). No issues there.
Finding 1 — Medium severity
File: litebox_shim_linux/src/syscalls/signal/mod.rs:266
Unsafe pattern:
fn is_on_stack(stack: &SigAltStack, sp: usize) -> bool {
if stack.flags.contains(SsFlags::DISABLE) {
return false;
}
let stack_start = stack.sp;
let stack_end = stack.sp + stack.size; // ← raw + on guest-supplied values
sp >= stack_start && sp < stack_end
}stack.sp and stack.size originate from guest sigaltstack(2) syscall arguments. While set_sigaltstack() currently validates them with checked_add before storing (line 312), the is_on_stack() function relies on that implicit invariant rather than defensive arithmetic. If the invariant is ever loosened or a new code path introduces an unvalidated SigAltStack, this would silently overflow in release builds or panic in debug builds.
Suggested fix:
let stack_end = stack.sp.wrapping_add(stack.size);Finding 2 — Medium severity
File: litebox_shim_linux/src/syscalls/signal/mod.rs:353
Unsafe pattern:
let sp = if switch_stacks {
altstack.sp + altstack.size // ← raw + on guest-supplied values
} else {
sp
};Same root cause as Finding 1: altstack.sp and altstack.size come from guest-provided sigaltstack(2) data. The invariant from set_sigaltstack() makes this safe today, but the pattern is fragile and inconsistent with the wrapping-arithmetic convention used in the adjacent signal-frame code.
Suggested fix:
let sp = if switch_stacks {
altstack.sp.wrapping_add(altstack.size)
} else {
sp
};Finding 3 — Low severity (ELF loader)
File: litebox_common_linux/src/loader.rs:420–464
Unsafe pattern:
// Only p_vaddr + p_memsz is validated; base_addr + p_vaddr is not.
let adjusted_vaddr = base_addr + p_vaddr; // line 420
let file_end = page_align_up(adjusted_vaddr + p_filesz); // line 422
let load_end = page_align_up(adjusted_vaddr + p_memsz); // line 423
// ...
let unaligned_file_end = adjusted_vaddr + p_filesz; // line 443
phdrs_addr = adjusted_vaddr + offset_in_segment; // line 464p_vaddr, p_filesz, p_memsz, and offset_in_segment come from ELF program headers. The code validates p_vaddr.checked_add(p_memsz).is_none() (line 410), but not base_addr.checked_add(p_vaddr). For ET_DYN binaries, base_addr is chosen by the host memory mapper; in practice the reservation bounds make overflow unlikely. For ET_EXEC (where base_addr = 0), the existing checked_add for p_vaddr + p_memsz is sufficient. Nonetheless, raw + on values derived (however indirectly) from file-supplied ELF headers is a fragile pattern that could become exploitable if the loading path or mapper changes.
Suggested fix: Add an explicit overflow check for base_addr + p_vaddr alongside the existing validation:
if p_memsz < p_filesz
|| p_vaddr.checked_add(p_memsz).is_none()
|| base_addr.checked_add(p_vaddr).is_none() // ← new check
|| ph.p_offset.checked_add(ph.p_filesz).is_none()
{
return Err(ElfLoadError::InvalidProgramHeader);
}
let adjusted_vaddr = base_addr + p_vaddr; // now safeAnd for adjusted_vaddr + p_filesz / + p_memsz — since after the above check base_addr + p_vaddr is known to not overflow, and p_vaddr + p_memsz is known to not overflow, the remaining additions are bounded. Alternatively use wrapping_add for defense in depth.
Summary table
| # | File | Line | Guest-derived values | Current protection | Risk |
|---|---|---|---|---|---|
| 1 | litebox_shim_linux/src/syscalls/signal/mod.rs |
266 | stack.sp, stack.size (via sigaltstack syscall) |
Validated in set_sigaltstack — implicit invariant |
Medium |
| 2 | litebox_shim_linux/src/syscalls/signal/mod.rs |
353 | altstack.sp, altstack.size (via sigaltstack syscall) |
Validated in set_sigaltstack — implicit invariant |
Medium |
| 3 | litebox_common_linux/src/loader.rs |
420–464 | p_vaddr, p_filesz, p_memsz, offset_in_segment (from ELF file) |
p_vaddr + p_memsz is checked; base_addr + p_vaddr is not |
Low |
Generated by Integer Overflow Scanner