]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix stack corruption in copy_initfile() on 32-bit
authorMichal Nowak <mnowak@isc.org>
Thu, 21 May 2026 07:31:03 +0000 (07:31 +0000)
committerMichal Nowak <mnowak@isc.org>
Thu, 21 May 2026 14:56:46 +0000 (16:56 +0200)
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
lib/dns/zone.c

index 4ab816c1f2a2007d84fd55975f41ab3a6043b362..3638e06c85529ffde4950552bd2da198b8e495b0 100644 (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];