mirror of
https://github.com/xroche/httrack.git
synced 2026-07-24 01:29:49 +03:00
proxy/store.c carried its own copy of htscache.c's old-format (.dat/.ndx) cache readers without the bounds hardening the engine copy got in #568. cache_brstr/cache_rstr trusted a length prefix from the cache file and wrote it into fixed buffers unbounded, and cache_rint/cache_rLLint used an unchecked sscanf result as a size or offset, so a crafted cache overflowed firstline[256] and the PT_Element fields and could wrap a malloc(size+1). Ports the engine's discipline into the proxy copy: thread the destination capacity through the readers and clamp while consuming the declared length, check every sscanf, allocate the body through a bounded helper, fix an index[index_id] off-by-one, and bound the startUrl/previous_save concatenations. Also casts the coucal void* key at the %s snprintf. The .dat/.ndx format is dead (zip only now), so this is defense-in-depth on the legacy reader; a corrupt-cache test guards it under the sanitizer CI.
22 lines
700 B
Bash
22 lines
700 B
Bash
#!/bin/bash
|
|
# A corrupt proxytrack .ndx must not overflow the fixed cache-read buffers. The
|
|
# sanitizer CI build turns any regression here into a hard stack/heap overflow.
|
|
|
|
set -euo pipefail
|
|
|
|
dir=$(mktemp -d)
|
|
trap 'rm -rf "$dir"' EXIT
|
|
|
|
# The first length-prefixed field declares far more than firstline[256] holds;
|
|
# cache_brstr must clamp the copy to the destination, not the declared length.
|
|
{
|
|
printf '4000\n'
|
|
head -c 4000 /dev/zero | tr '\0' 'A'
|
|
} >"$dir/foo.ndx"
|
|
: >"$dir/foo.dat" # cache_brstr runs only when the sibling .dat opens
|
|
|
|
proxytrack --convert "$dir/out.arc" "$dir/foo.ndx" >/dev/null 2>&1 || {
|
|
echo "FAIL: proxytrack crashed/errored on a corrupt cache index"
|
|
exit 1
|
|
}
|