Skip to content

Commit bc12dad

Browse files
committed
quic_record_append: return correct code
0-return from quic_record_append is an error. `quic_record_complete(qr) || len == 0` is not an error condition. We should return as normal on success. The issue is that passing in buffers with length 1 then 3 causes `qr_length` (in `quic_record_make`) to return 0. Then when `quic_record_append` gets called the `len` gets consumed by the first `if` and `len == 0` is true. This causes the error return which is not correct behaviour. Reported in wolfSSL#8156. Reproducing is a bit tricky. I couldn't get the docker to work. First setup ngtcp2 as described in https://github.com/ngtcp2/ngtcp2/pkgs/container/ngtcp2-interop. The Relevant steps are (I tested with master/main branches of all libs): ``` $ git clone --depth 1 -b v5.7.4-stable https://github.com/wolfSSL/wolfssl $ cd wolfssl $ autoreconf -i $ # For wolfSSL < v5.6.6, append --enable-quic. $ ./configure --prefix=$PWD/build \ --enable-all --enable-aesni --enable-harden --enable-keylog-export \ --disable-ech $ make -j$(nproc) $ make install $ cd .. $ git clone --recursive https://github.com/ngtcp2/nghttp3 $ cd nghttp3 $ autoreconf -i $ ./configure --prefix=$PWD/build --enable-lib-only $ make -j$(nproc) check $ make install $ cd .. $ git clone --recursive https://github.com/ngtcp2/ngtcp2 $ cd ngtcp2 $ autoreconf -i $ # For Mac users who have installed libev with MacPorts, append $ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev" $ ./configure PKG_CONFIG_PATH=$PWD/../wolfssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig \ --with-wolfssl $ make -j$(nproc) check ``` Download and unzip https://github.com/user-attachments/files/17621329/failing.pcap.zip From the ngtcp2 dir: ``` ./examples/wsslserver 127.0.0.1 44433 /path/to/wolfssl/certs/server-key.pem /path/to/wolfssl/certs/server-cert.pem ``` Then run the following python script (`failing.pcap` has to be available in the running dir) (probably needs to be run as `sudo`): ``` from scapy.utils import rdpcap, PcapNgReader from scapy.all import * reader = PcapNgReader("failing.pcap") for i in reader: p = i[IP] p.dport = 44433 p.dst = "127.0.0.1" p[UDP].chksum=0 p.display() send(p) ``` Then observe the log line: ``` I00000000 0xa48accb7b49ec1556ac7111c64d3a4572a81 frm tx 625216795 Initial CONNECTION_CLOSE(0x1c) error_code=CRYPTO_ERROR(0x100) frame_type=0 reason_len=0 reason=[] ``` You can also use `gdb` and place a break inside the following section in `wolfssl/src/quic.c`. ``` if (quic_record_complete(qr) || len == 0) { return 0; } ```
1 parent 78c4a04 commit bc12dad

File tree

2 files changed

+12
-11
lines changed

2 files changed

+12
-11
lines changed

src/quic.c

+8-10
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,15 @@ static int quic_record_append(WOLFSSL *ssl, QuicRecord *qr, const uint8_t *data,
154154
}
155155
}
156156

157-
if (quic_record_complete(qr) || len == 0) {
158-
return 0;
159-
}
160-
161-
missing = qr->len - qr->end;
162-
if (len > missing) {
163-
len = missing;
157+
if (!quic_record_complete(qr) && len != 0) {
158+
missing = qr->len - qr->end;
159+
if (len > missing) {
160+
len = missing;
161+
}
162+
XMEMCPY(qr->data + qr->end, data, len);
163+
qr->end += (word32)len;
164+
consumed += len;
164165
}
165-
XMEMCPY(qr->data + qr->end, data, len);
166-
qr->end += (word32)len;
167-
consumed += len;
168166

169167
cleanup:
170168
*pconsumed = (ret == WOLFSSL_SUCCESS) ? consumed : 0;

tests/quic.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,10 @@ static int test_provide_quic_data(void) {
287287
*/
288288
AssertNotNull(ssl = wolfSSL_new(ctx));
289289
len = fake_record(1, 100, lbuffer);
290-
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer, len, 0));
290+
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer, 1, 0));
291+
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer+1, 3, 0));
292+
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer+4, len, 0)
293+
);
291294
len = fake_record(2, 1523, lbuffer);
292295
AssertTrue(provide_data(ssl, wolfssl_encryption_handshake, lbuffer, len, 0));
293296
len = fake_record(2, 1, lbuffer);

0 commit comments

Comments
 (0)