]> The Tcpdump Group git mirrors - tcpdump/commitdiff
QUIC: Fix a pointer overflow with 32-bit executable
authorFrancois-Xavier Le Bail <[email protected]>
Sat, 12 Aug 2023 06:25:14 +0000 (08:25 +0200)
committerFrancois-Xavier Le Bail <[email protected]>
Sat, 12 Aug 2023 18:54:58 +0000 (20:54 +0200)
When decoding an IPv6 Jumbo frame, the lenght of the payload may be huge
(e.g. 201311154). This gives a huge length to udp_print() and then
to quic_print() (e.g. 201311130). With 32-bit executable, addding the
length to the pointer can overflow, like:

print-quic.c:277:26: runtime error: pointer index expression with base
0xf42032c0 overflowed to 0x001ff65a

Use ND_BYTES_AVAILABLE_AFTER() to assign the 'end' pointer.

quic_print(): Remove the parameter 'len' no longer used.

Add a test file.

Update the output of a test accordingly (packet 10 not truncated).

netdissect.h
print-quic.c
print-udp.c
tests/TESTLIST
tests/quic_32_bit_pointer_overflow.out [new file with mode: 0644]
tests/quic_32_bit_pointer_overflow.pcap [new file with mode: 0644]
tests/quic_handshake_truncated.out

index 6bbac0b10488a8126bd7ed6ef32a7b6908d96629..dcdc2548c3acce7f2d1881b3486ccdbb5294ec7a 100644 (file)
@@ -724,7 +724,7 @@ extern void ptp_print(netdissect_options *, const u_char *, u_int);
 extern const char *q922_string(netdissect_options *, const u_char *, u_int);
 extern void q933_print(netdissect_options *, const u_char *, u_int);
 extern int quic_detect(netdissect_options *, const u_char *, const u_int);
-extern void quic_print(netdissect_options *, const u_char *, const u_int);
+extern void quic_print(netdissect_options *, const u_char *);
 extern void radius_print(netdissect_options *, const u_char *, u_int);
 extern void resp_print(netdissect_options *, const u_char *, u_int);
 extern void rip_print(netdissect_options *, const u_char *, u_int);
index eb8120b22fad6003ebd15253ec6cb1f2827001d4..acdbaf6afdf792ed3cfbe74c253c433124f25afa 100644 (file)
@@ -272,9 +272,9 @@ quic_print_packet(netdissect_options *ndo, const u_char *bp, const u_char *end)
 }
 
 void
-quic_print(netdissect_options *ndo, const u_char *bp, const u_int len)
+quic_print(netdissect_options *ndo, const u_char *bp)
 {
-       const uint8_t *end = bp + len;
+       const uint8_t *end = bp + ND_BYTES_AVAILABLE_AFTER(bp);
 
        ndo->ndo_protocol = "quic";
        nd_print_protocol(ndo);
index d2359dda01d2e240bd700a8a7276ecc3019c9d1e..e589b136a751d27b460c9d20205dce074a8d2161 100644 (file)
@@ -464,7 +464,7 @@ udp_print(netdissect_options *ndo, const u_char *bp, u_int length,
                        domain_print(ndo, cp, length, FALSE, FALSE);
                        break;
                case PT_QUIC:
-                       quic_print(ndo, cp, length);
+                       quic_print(ndo, cp);
                        break;
                }
                return;
@@ -674,7 +674,7 @@ udp_print(netdissect_options *ndo, const u_char *bp, u_int length,
                        someip_print(ndo, cp, length);
                else if (IS_SRC_OR_DST_PORT(HTTPS_PORT) &&
                         quic_detect(ndo, cp, length))
-                       quic_print(ndo, cp, length);
+                       quic_print(ndo, cp);
                else if (sport == BCM_LI_PORT)
                        bcm_li_print(ndo, cp, length);
                else {
index b64496ab06c6937e122954948c9f81bb55310e25..2ee9ec677b3cbd335872f9a6842fdf87c8a655c9 100644 (file)
@@ -907,6 +907,7 @@ quic_handshake                      quic_handshake.pcap             quic_handshake.out      -v
 quic_handshake_truncated       quic_handshake_truncated.pcap   quic_handshake_truncated.out    -v
 quic_retry                     quic_retry.pcap                 quic_retry.out  -v
 gquic                          gquic.pcap                      gquic.out       -v
+quic_32_bit_pointer_overflow quic_32_bit_pointer_overflow.pcap quic_32_bit_pointer_overflow.out
 
 # GRE keepalives, CDP over GRE
 various_gre                    various_gre.pcap                various_gre.out -v
diff --git a/tests/quic_32_bit_pointer_overflow.out b/tests/quic_32_bit_pointer_overflow.out
new file mode 100644 (file)
index 0000000..bb0aae4
--- /dev/null
@@ -0,0 +1 @@
+    1  14:32:46.453540455 IP6 ::8:46:ee:102:202:202 > 202:200:0:fe7e:b65f:677a:82b:601: HBH truncated-ip6 - 201252743 bytes missing!0 > 443: quic, initial, vb2a10200, dcid 00000100, length 1 [|quic]
diff --git a/tests/quic_32_bit_pointer_overflow.pcap b/tests/quic_32_bit_pointer_overflow.pcap
new file mode 100644 (file)
index 0000000..2011625
Binary files /dev/null and b/tests/quic_32_bit_pointer_overflow.pcap differ
index 00882b321e996307b7ff3fe13c21bbcd643ae475..909b61910bf522c895eff90a6c83fa6a26a9a72d 100644 (file)
@@ -7,7 +7,7 @@
     7  19:57:02.485464 IP6 (class 0x02, flowlabel 0x70e00, hlim 64, next-header UDP (17) payload length: 81) ::1.65165 > ::1.443: [bad udp cksum 0x0064 -> 0x9855!] quic, handshake, dcid beb256567ee5698c, length 56
     8  19:57:02.485711 IP6 (class 0x02, flowlabel 0x50700, hlim 64, next-header UDP (17) payload length: 50) ::1.443 > ::1.65165: [bad udp cksum 0x0045 -> 0xca20!] quic, handshake, scid beb256567ee5698c, length 25
     9  19:57:02.485809 IP6 (class 0x02, flowlabel 0x50700, hlim 64, next-header UDP (17) payload length: 29) ::1.443 > ::1.65165: [bad udp cksum 0x0030 -> 0x4f93!] quic, protected
-   10  19:57:02.486075 IP6 (class 0x02, flowlabel 0x50700, hlim 64, next-header UDP (17) payload length: 250) ::1.443 > ::1.65165: quic, protected [|quic]
+   10  19:57:02.486075 IP6 (class 0x02, flowlabel 0x50700, hlim 64, next-header UDP (17) payload length: 250) ::1.443 > ::1.65165: quic, protected
    11  19:57:02.486726 IP6 (class 0x02, flowlabel 0x70e00, hlim 64, next-header UDP (17) payload length: 39) ::1.65165 > ::1.443: [bad udp cksum 0x003a -> 0x38d3!] quic, protected, dcid beb256567ee5698c
    12  19:57:02.487067 IP6 (class 0x02, flowlabel 0x70e00, hlim 64, next-header UDP (17) payload length: 37) ::1.65165 > ::1.443: [bad udp cksum 0x0038 -> 0x3993!] quic, protected, dcid beb256567ee5698c
    13  19:57:02.487144 IP6 (class 0x02, flowlabel 0x70e00, hlim 64, next-header UDP (17) payload length: 37) ::1.65165 > ::1.443: [bad udp cksum 0x0038 -> 0x7ae0!] quic, protected, dcid beb256567ee5698c