]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Detect uncleared libcrypto errors in rdata processing
authorMark Andrews <marka@isc.org>
Wed, 28 Jun 2023 06:28:57 +0000 (16:28 +1000)
committerMark Andrews <marka@isc.org>
Fri, 1 Sep 2023 02:01:20 +0000 (12:01 +1000)
If libcrypto errors are not cleared slow memory leaks occur which
are not detected at shutdown.

tests/dns/Makefile.am
tests/dns/rdata_test.c

index aa9f1ea74462b8dd12f193b8e97eb79bc11359f3..921678ca908424bcb7c853c3f16ceb65c3e74ed7 100644 (file)
@@ -8,8 +8,8 @@ AM_CPPFLAGS +=                          \
        $(KRB5_CFLAGS)                  \
        -DSRCDIR=\"$(abs_srcdir)\"      \
        -DBUILDDIR=\"$(abs_builddir)\"  \
-       -I$(top_srcdir)/lib/isc         \
-       -I$(top_srcdir)/lib/dns
+       -I$(top_srcdir)/lib/dns         \
+       -I$(top_srcdir)/lib/isc
 
 LDADD +=                               \
        $(LIBISC_LIBS)                  \
@@ -108,6 +108,14 @@ rsa_test_CPPFLAGS =                \
        $(AM_CPPFLAGS)          \
        $(OPENSSL_CFLAGS)
 
+rdata_test_CPPFLAGS =          \
+       $(AM_CPPFLAGS)          \
+       $(OPENSSL_CFLAGS)
+
+rdata_test_LDADD =             \
+       $(LDADD)                \
+       $(OPENSSL_LIBS)
+
 EXTRA_sigs_test_DEPENDENCIES = testdata/master/master18.data
 CLEANFILES += $(EXTRA_sigs_test_DEPENDENCIES)
 
index befe57986c184a3fa46891e46ee72566f4fea847..8c197d8498a8eaf809cbd1ccda627798670e8ddd 100644 (file)
@@ -24,6 +24,9 @@
 #define UNIT_TESTING
 
 #include <cmocka.h>
+#include <openssl_shim.h>
+
+#include <openssl/err.h>
 
 #include <isc/commandline.h>
 #include <isc/hex.h>
@@ -122,6 +125,23 @@ typedef struct wire_ok {
 #define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, 0, FIRST, __VA_ARGS__)
 #define WIRE_SENTINEL()                 WIRE_TEST(false, 0)
 
+static void
+detect_uncleared_libcrypto_error(void) {
+       const char *file, *func, *data;
+       int line, flags;
+       long err;
+       bool leak = false;
+       while ((err = ERR_get_error_all(&file, &line, &func, &data, &flags)) !=
+              0L)
+       {
+               fprintf(stderr,
+                       "# Uncleared libcrypto error: %s:%d %s %s %ld %x\n",
+                       file, line, func, data, err, flags);
+               leak = true;
+       }
+       assert_false(leak);
+}
+
 /*
  * Call dns_rdata_fromwire() for data in 'src', which is 'srclen' octets in
  * size and represents RDATA of given 'type' and 'class'.  Store the resulting
@@ -152,6 +172,7 @@ wire_to_rdata(const unsigned char *src, size_t srclen, dns_rdataclass_t rdclass,
         */
        result = dns_rdata_fromwire(rdata, rdclass, type, &source,
                                    DNS_DECOMPRESS_ALWAYS, &target);
+       detect_uncleared_libcrypto_error();
 
        return (result);
 }
@@ -176,6 +197,7 @@ rdata_towire(dns_rdata_t *rdata, unsigned char *dst, size_t dstlen,
         */
        dns_compress_init(&cctx, mctx, 0);
        result = dns_rdata_towire(rdata, &cctx, &target);
+       detect_uncleared_libcrypto_error();
        dns_compress_invalidate(&cctx);
 
        *length = isc_buffer_usedlength(&target);
@@ -269,6 +291,7 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize,
         * Convert from uncompressed wire form into type-specific struct.
         */
        result = dns_rdata_tostruct(rdata, rdata_struct, NULL);
+       detect_uncleared_libcrypto_error();
        assert_int_equal(result, ISC_R_SUCCESS);
 
        /*
@@ -401,6 +424,7 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
         */
        isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
        result = dns_rdata_totext(&rdata, NULL, &target);
+       detect_uncleared_libcrypto_error();
        if (result != ISC_R_SUCCESS && debug) {
                size_t i;
                fprintf(stdout, "# dns_rdata_totext -> %s",
@@ -489,6 +513,7 @@ check_text_conversions(dns_rdata_t *rdata) {
         */
        isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
        result = dns_rdata_totext(rdata, NULL, &target);
+       detect_uncleared_libcrypto_error();
        assert_int_equal(result, ISC_R_SUCCESS);
        /*
         * Ensure buf_totext is properly NUL terminated as dns_rdata_totext()
@@ -542,6 +567,7 @@ check_multiline_text_conversions(dns_rdata_t *rdata) {
        flags = dns_master_styleflags(&dns_master_style_default);
        result = dns_rdata_tofmttext(rdata, dns_rootname, flags, 80 - 32, 4,
                                     "\n", &target);
+       detect_uncleared_libcrypto_error();
        assert_int_equal(result, ISC_R_SUCCESS);
        /*
         * Ensure buf_totext is properly NUL terminated as
@@ -709,6 +735,7 @@ check_compare_ok_single(const compare_ok_t *compare_ok,
        }
 
        answer = dns_rdata_compare(&rdata1, &rdata2);
+       detect_uncleared_libcrypto_error();
        if (compare_ok->answer == 0 && answer != 0) {
                fail_msg("# line %d: dns_rdata_compare('%s', '%s'): "
                         "expected equal, got %s",