named-checkconf *** buffer overflow detected *** with -D_FORTIFY_SOURCE=3
Using gcc12, one can utilize -D_FORTIFY_SOURCE=3
that shows the following bug:
$ gdb ./bin/check/named-checkconf
...
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
44 return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0;
(gdb) bt
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1 0x00007ffff76f31e3 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
#2 0x00007ffff76a3306 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3 0x00007ffff768c813 in __GI_abort () at abort.c:79
#4 0x00007ffff76e61b7 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff782c3cf "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#5 0x00007ffff778b30a in __GI___fortify_fail (msg=msg@entry=0x7ffff782c375 "buffer overflow detected") at fortify_fail.c:26
#6 0x00007ffff77898b6 in __GI___chk_fail () at chk_fail.c:28
#7 0x00007ffff7789485 in ___snprintf_chk (s=<optimized out>, maxlen=maxlen@entry=1152, flag=flag@entry=2, slen=<optimized out>, format=format@entry=0x41ffef "%u/%s") at snprintf_chk.c:29
#8 0x000000000023293d in snprintf (__fmt=0x41ffef "%u/%s", __n=1152, __s=<optimized out>) at /usr/include/bits/stdio2.h:71
#9 check_zoneconf (zconfig=0x492b70, voptions=voptions@entry=0x0, config=config@entry=0x491a30, symtab=<optimized out>, files=files@entry=0x4919e0, keydirs=keydirs@entry=0x48f400, inview=0x48faa0, viewname=<optimized out>, defclass=1, actx=0x492760, logctx=0x49cc60, mctx=0x490360) at check.c:2500
#10 0x00000000002349b3 in check_viewconf (config=config@entry=0x491a30, voptions=voptions@entry=0x0, viewname=viewname@entry=0x0, vclass=vclass@entry=1, files=0x4919e0, keydirs=0x48f400, check_plugins=true, inview=<optimized out>, logctx=0x49cc60, mctx=0x490360) at check.c:4569
#11 0x0000000000237a3d in bind9_check_namedconf (config=0x491a30, check_plugins=true, logctx=<optimized out>, mctx=0x490360) at check.c:5253
#12 0x000000000022bb74 in main (argc=<optimized out>, argv=0x7fffffffdb28) at ./named-checkconf.c:739
That is caused by wrong order of len -= strlen(tmp);
and tmp += strlen(tmp);
. If you run it as it is, then you end with len -= 0
, because tmp
points to \0
.
Please apply the following patch:
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index d2cc4bf..0f6c700 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -2495,8 +2495,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
} else if (dns_name_isula(zname)) {
ula = true;
}
- tmp += strlen(tmp);
len -= strlen(tmp);
+ tmp += strlen(tmp);
(void)snprintf(tmp, len, "%u/%s", zclass,
(ztype == CFG_ZONE_INVIEW) ? target
: (viewname != NULL) ? viewname
@@ -3244,8 +3244,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
char *tmp = keydirbuf;
size_t len = sizeof(keydirbuf);
dns_name_format(zname, keydirbuf, sizeof(keydirbuf));
- tmp += strlen(tmp);
len -= strlen(tmp);
+ tmp += strlen(tmp);
(void)snprintf(tmp, len, "/%s", (dir == NULL) ? "(null)" : dir);
tresult = keydirexist(zconfig, (const char *)keydirbuf,
kaspname, keydirs, logctx, mctx);