From c424594b04439e2c29af41c66848b6b208f35310 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 25 Jun 2020 10:18:43 +0300 Subject: [PATCH] evdns: do not pass NULL to memcpy() in evdns_server_request_format_response() In case of OPT pseudo-RR `class` field is treated as a requestor's UDP payload size, and class will have 512 (DNS_MAX_UDP_SIZE), and data is NULL: (gdb) p *item $4 = { next = 0x0, name = 0x602000000130 "", type = 41, class = 512, ttl = 0, is_name = 0 '\000', datalen = 0, data = 0x0 } And UBSAN will reports: ../evdns.c:2493:5: runtime error: null pointer passed as argument 2, which is declared to never be null #0 0x7ffff70b65bb in evdns_server_request_format_response ../evdns.c:2493 #1 0x7ffff70b706b in evdns_server_request_respond ../evdns.c:2529 #2 0x5555557975ab in regress_dns_server_cb ../test/regress_testutils.c:263 #3 0x7ffff70a8489 in request_parse ../evdns.c:1576 #4 0x7ffff70aa445 in server_udp_port_read ../evdns.c:1726 #5 0x7ffff70ac5cc in server_port_ready_callback ../evdns.c:1849 #6 0x7ffff6d3054c in event_persist_closure ../event.c:1645 #7 0x7ffff6d311cd in event_process_active_single_queue ../event.c:1704 #8 0x7ffff6d33258 in event_process_active ../event.c:1805 #9 0x7ffff6d361b5 in event_base_loop ../event.c:2047 #10 0x7ffff6d334ac in event_base_dispatch ../event.c:1839 #11 0x555555739df2 in test_edns ../test/regress_dns.c:2639 #12 0x5555557b9e96 in testcase_run_bare_ ../test/tinytest.c:173 #13 0x5555557ba8f0 in testcase_run_one ../test/tinytest.c:333 #14 0x5555557bc9a0 in tinytest_main ../test/tinytest.c:527 #15 0x555555787faa in main ../test/regress_main.c:528 #16 0x7ffff606c001 in __libc_start_main (/usr/lib/libc.so.6+0x27001) #17 0x55555569436d in _start (/src/le/libevent/.cmake-debug/bin/regress+0x14036d) --- evdns.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/evdns.c b/evdns.c index aeee5811..8df18568 100644 --- a/evdns.c +++ b/evdns.c @@ -2490,8 +2490,12 @@ evdns_server_request_format_response(struct server_request *req, int err) APPEND16(item->datalen); if (j+item->datalen > (off_t)buf_len) goto overflow; - memcpy(buf+j, item->data, item->datalen); - j += item->datalen; + if (item->data) { + memcpy(buf+j, item->data, item->datalen); + j += item->datalen; + } else { + EVUTIL_ASSERT(item->datalen == 0); + } } item = item->next; } -- 2.40.0