Fix stack corruption in copy_initfile() on 32-bit

copy_initfile() declared a size_t local variable to receive the size of
the initial file and passed it to isc_file_getsizefd() with an explicit
(off_t *) cast. On 32-bit platforms with _FILE_OFFSET_BITS=64, off_t is
8 bytes while size_t is only 4 bytes, so isc_file_getsizefd()'s
"*size = stats.st_size;" writes 8 bytes into the 4-byte slot and
clobbers the adjacent "output" FILE * on the stack. The next iteration
of the read/write loop then calls clearerr() through a NULL pointer and
named crashes with SIGSEGV.

This is triggered whenever a zone with an initial-file (e.g. one
configured via a template) is loaded for the first time, so on 32-bit
the addzone and masterfile system tests crash named in ns2 with cores.

Declare "len" as off_t to match the API and drop the unsafe cast.

Assisted-by: Claude:claude-opus-4-7
This commit is contained in:
Michal Nowak 2026-05-21 07:31:03 +00:00
parent b076c43b1c
commit 2ef6f0b4f2

View file

@ -1109,12 +1109,12 @@ static isc_result_t
copy_initfile(dns_zone_t *zone) {
isc_result_t result;
FILE *input = NULL, *output = NULL;
size_t len;
off_t len;
CHECK(isc_stdio_open(zone->initfile, "r", &input));
CHECK(isc_stdio_open(zone->masterfile, "w", &output));
CHECK(isc_file_getsizefd(fileno(input), (off_t *)&len));
CHECK(isc_file_getsizefd(fileno(input), &len));
do {
char buf[BUFSIZ];