kdig: double-free on some malformed responses from QUIC server
This is probably minor, but when a QUIC server responds with a specifically malformed query, it may result in a double-free in kdig
.
I can consistently reproduce this with the echo
branch of my https://github.com/Spiffyk/doq-proxy/tree/echo fork, with the following patch:
diff --git a/cmd/echo/main.go b/cmd/echo/main.go
index 5d0f589..f742424 100644
--- a/cmd/echo/main.go
+++ b/cmd/echo/main.go
@@ -158,7 +158,8 @@ func handleStream(l log.Logger, stream quic.Stream) error {
return fmt.Errorf("read query: %w", err)
}
- _, err = stream.Write(data[:n])
+ // nocheckin
+ _, err = stream.Write(data[2:n])
if err != nil {
return fmt.Errorf("send response: %w", err)
}
and the following kdig
invocation:
$ kdig @<doq-address>@<doq-port> +quic example.com
I get the following output:
$ kdig @::1@5853 +quic example.com
;; WARNING: can't receive reply from ::1@5853(QUIC)
;; WARNING: can't receive reply from ::1@5853(QUIC)
;; WARNING: can't receive reply from ::1@5853(QUIC)
;; ERROR: failed to query server ::1@5853(UDP)
free(): double free detected in tcache 2
Aborted (core dumped)
Additionally, my backtrace:
(gdb) bt
#0 0x00007f236b96d26c in ?? () from /usr/lib/libc.so.6
#1 0x00007f236b91da08 in raise () from /usr/lib/libc.so.6
#2 0x00007f236b906538 in abort () from /usr/lib/libc.so.6
#3 0x00007f236b9072db in ?? () from /usr/lib/libc.so.6
#4 0x00007f236b9771b7 in ?? () from /usr/lib/libc.so.6
#5 0x00007f236b9796ae in ?? () from /usr/lib/libc.so.6
#6 0x00007f236b97bcb3 in free () from /usr/lib/libc.so.6
#7 0x000055a50a029c8e in quic_ctx_deinit (ctx=0x7ffdac0c7f08) at utils/common/quic.c:853
#8 0x000055a50a026f53 in net_clean (net=0x7ffdac0c7e10) at utils/common/netio.c:933
#9 0x000055a50a018ba8 in process_query (query=0x55a50a872fd0, net=0x7ffdac0c7e10) at utils/kdig/kdig_exec.c:935
#10 0x000055a50a019aec in kdig_exec (params=0x7ffdac0c80b0) at utils/kdig/kdig_exec.c:1276
#11 0x000055a50a019c5f in main (argc=4, argv=0x7ffdac0c8208) at utils/kdig/kdig_main.c:34