Skip to content

Commit

Permalink
quic_record_append: return correct code
Browse files Browse the repository at this point in the history
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 #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;
    }
```
  • Loading branch information
julek-wolfssl authored and Juliusz Sosinowicz committed Jan 16, 2025
1 parent e76186f commit 88c6349
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 11 deletions.
18 changes: 8 additions & 10 deletions src/quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,15 @@ static int quic_record_append(WOLFSSL *ssl, QuicRecord *qr, const uint8_t *data,
}
}

if (quic_record_complete(qr) || len == 0) {
return 0;
}

missing = qr->len - qr->end;
if (len > missing) {
len = missing;
if (!quic_record_complete(qr) && len != 0) {
missing = qr->len - qr->end;
if (len > missing) {
len = missing;
}
XMEMCPY(qr->data + qr->end, data, len);
qr->end += (word32)len;
consumed += len;
}
XMEMCPY(qr->data + qr->end, data, len);
qr->end += (word32)len;
consumed += len;

cleanup:
*pconsumed = (ret == WOLFSSL_SUCCESS) ? consumed : 0;
Expand Down
5 changes: 4 additions & 1 deletion tests/quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,10 @@ static int test_provide_quic_data(void) {
*/
AssertNotNull(ssl = wolfSSL_new(ctx));
len = fake_record(1, 100, lbuffer);
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer, len, 0));
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer, 1, 0));
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer+1, 3, 0));
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer+4, len, 0)
);
len = fake_record(2, 1523, lbuffer);
AssertTrue(provide_data(ssl, wolfssl_encryption_handshake, lbuffer, len, 0));
len = fake_record(2, 1, lbuffer);
Expand Down

0 comments on commit 88c6349

Please sign in to comment.