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
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];