diff --git a/CHANGES b/CHANGES index 5414629ae9..d1495ddb60 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3894. [bug] Buffers in isc_print_vsnprintf were not properly + initialized leading to potential overflows when + printing out quad values. [RT #36505] + 3892. [bug] Setting '-t aaaa' in .digrc had unintended side effects. [RT #36452] diff --git a/lib/isc/include/isc/print.h b/lib/isc/include/isc/print.h index cd1e38eaf6..84c98b9770 100644 --- a/lib/isc/include/isc/print.h +++ b/lib/isc/include/isc/print.h @@ -38,10 +38,13 @@ */ #if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDVSNPRINTF +#undef snprintf +#undef vsnprintf #endif #if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDSPRINTF +#undef sprintf #endif /*** diff --git a/lib/isc/print.c b/lib/isc/print.c index a5e5ba6699..4d5ae50d2f 100644 --- a/lib/isc/print.c +++ b/lib/isc/print.c @@ -260,7 +260,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (hi != 0) sprintf(buf, "%lu", hi); else - buf[0] = '\n'; + buf[0] = '\0'; sprintf(buf + strlen(buf), "%lu", mid); sprintf(buf + strlen(buf), "%lu", lo); } @@ -317,7 +317,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (hi != 0) sprintf(buf, "%lu", hi); else - buf[0] = '\n'; + buf[0] = '\0'; sprintf(buf + strlen(buf), "%lu", mid); sprintf(buf + strlen(buf), "%lu", lo); } diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in index a278a67d22..87004793be 100644 --- a/lib/isc/tests/Makefile.in +++ b/lib/isc/tests/Makefile.in @@ -38,12 +38,12 @@ OBJS = isctest.@O@ SRCS = isctest.c taskpool_test.c hash_test.c lex_test.c \ sockaddr_test.c safe_test.c symtab_test.c parse_test.c \ - regex_test.c + print_test.c regex_test.c SUBDIRS = TARGETS = taskpool_test@EXEEXT@ hash_test@EXEEXT@ lex_test@EXEEXT@ \ sockaddr_test@EXEEXT@ safe_test@EXEEXT@ symtab_test@EXEEXT@ \ - parse_test@EXEEXT@ regex_test@EXEEXT@ + parse_test@EXEEXT@ print_test@EXEEXT@ regex_test@EXEEXT@ @BIND9_MAKE_RULES@ @@ -71,6 +71,10 @@ sockaddr_test@EXEEXT@: sockaddr_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sockaddr_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} +print_test@EXEEXT@: print_test.@O@ ${ISCDEPLIBS} ${top_srcdir}/lib/isc/print.c + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + print_test.@O@ ${ISCLIBS} ${LIBS} + regex_test@EXEEXT@: regex_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ regex_test.@O@ ${ISCLIBS} ${LIBS} diff --git a/lib/isc/tests/print_test.c b/lib/isc/tests/print_test.c new file mode 100644 index 0000000000..3b5ac48dbc --- /dev/null +++ b/lib/isc/tests/print_test.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include +#include +#include + +/* + * Workout if we need to force the inclusion of print.c so we can test + * it on all platforms even if we don't include it in libisc. + */ +#include +#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && !defined(ISC_PLATFORM_NEEDSPRINTF) +#define ISC__PRINT_SOURCE +#include "../print.c" +#else +#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) || !defined(ISC_PLATFORM_NEEDSPRINTF) +#define ISC__PRINT_SOURCE +#endif +#include +#include +#include +#endif + +ATF_TC(snprintf); +ATF_TC_HEAD(snprintf, tc) { + atf_tc_set_md_var(tc, "descr", "snprintf implementation"); +} +ATF_TC_BODY(snprintf, tc) { + char buf[10000]; + isc_uint64_t ll = 8589934592ULL; + int n; + + UNUSED(tc); + + /* + * 4294967296 <= 8589934592 < 1000000000^2 to verify fix for + * RT#36505. + */ + + memset(buf, 0xff, sizeof(buf)); + n = isc_print_snprintf(buf, sizeof(buf), "%qu", ll); + ATF_CHECK_EQ(n, 10); + ATF_CHECK_STREQ(buf, "8589934592"); + + memset(buf, 0xff, sizeof(buf)); + n = isc_print_snprintf(buf, sizeof(buf), "%llu", ll); + ATF_CHECK_EQ(n, 10); + ATF_CHECK_STREQ(buf, "8589934592"); +} + +/* + * Main + */ +ATF_TP_ADD_TCS(tp) { + ATF_TP_ADD_TC(tp, snprintf); + return (atf_no_error()); +}