Refactor record padding handling to eliminate middle padding pattern#10149
Conversation
240bdfa to
29a1c54
Compare
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Refactors TLS record padding handling so padSz is accounted for once per record (in ProcessReply/DoProcessReplyEx) instead of being applied and “corrected” within each individual message handler.
Changes:
- Removes per-message
padSzindex advancement across TLS 1.3 and (D)TLS message handlers. - Adjusts
DoProcessReplyExto treatcurSizeas content-only by subtractingpadSz, and addspadSzonce when the record is fully processed. - Updates multi-message record flow to eliminate the prior “middle padding” correction, and restricts buffer shrinking during multi-message processing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/tls13.c | Removes per-handler padSz advancement so TLS 1.3 handlers advance by content length only. |
| src/internal.c | Centralizes padSz accounting in DoProcessReplyEx, updating message parsing logic and removing old padding correction paths. |
Comments suppressed due to low confidence (4)
src/internal.c:1
- Subtracting
padSzfromssl->curSizewithout first verifyingcurSize >= padSzcan underflow on malformed/truncated records and corrupt subsequent parsing/state. Add a guard (e.g., ifssl->curSize < ssl->keys.padSzreturn a length/buffer error) before performing the subtraction.
src/internal.c:1 - Advancing
inputBuffer.idxbypadSzhas no bounds validation. If padding/tag bytes are missing (corrupted/truncated input),idxcan jump beyond the actual buffered record data and leave the connection state inconsistent. Add a bounds check before incrementing (e.g., ensureidx + padSzdoes not exceed the available buffered data for the current record) and fail with a parse error if it would.
src/internal.c:1 inputLengthis reduced bypadSzwithout checking thatinputLength >= padSz. When the remaining buffered bytes are smaller thanpadSz, this will underflow (likely to a very largeword32) and can cause oversized copies/allocations or out-of-bounds reads later. Add an explicit check before subtracting and error out when insufficient bytes remain.
src/internal.c:1- The parameter
sizeis used (if (size)), so(void)size;is redundant and can be removed to reduce confusion.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Retest this please history lost........ |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (3)
src/internal.c:1
ssl->curSizeis an unsigned type; subtractingpadSzcan underflow ifpadSz > curSize(e.g., malformed/short records or ifpadSzis unexpectedly large), which would inflatecurSizeand break subsequent bounds checks (including the newcurStartIdx + curSizecalculations). Make this subtraction conditional onssl->curSize >= ssl->keys.padSz(return an error likeBUFFER_E/LENGTH_ERRORotherwise), and avoid truncatingpadSztoword16when comparing/subtracting.
src/internal.c:1- This DTLS 'drop record outside receiving window' path adds
ssl->keys.padSzunconditionally, butcurSizeis only reduced bypadSzwhenIsEncryptionOn(ssl, 0)is true. If encryption is off (or ifpadSzis stale from a prior encrypted record), this can skip too far and desynchronize parsing. AddpadSzhere only when the current record is encrypted (or ensurepadSzis reset to 0 for plaintext records before this path).
src/internal.c:1 - After advancing
inputBuffer.idxbypadSz, the code only checks>= length(and returns), but does not preventidxfrom becoming> length. LeavinginputBuffer.idxpast the buffer end can violate invariants for subsequent calls/paths. Add an explicitif (idx > length) return BUFFER_E;(or equivalent) immediately after theidx += padSzincrement (and similarly in otherpadSz-advance early-return paths).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
dgarske
left a comment
There was a problem hiding this comment.
🐺 Skoll Code Review
Overall recommendation: APPROVE
Findings: 4 total — 3 posted, 2 skipped
Posted findings
- [Medium] Missing defensive guard before
curSize -= padSzcould allow word16 underflow —src/internal.c:23184-23185 - [Medium] Callers of message handlers still pass
inputBuffer.lengthas totalSz, not content boundary —src/internal.c:23286-23289,23306-23309,23343-23346,23360-23362 - [Medium] No dedicated test for multi-message encrypted record processing after refactoring —
src/internal.c:23654-23695
Skipped findings
- [Low] Truncation cast of word32 padSz to word16 suppresses potential warnings
- [Medium] Callers of message handlers still pass
inputBuffer.lengthas totalSz, not content boundary
Review generated by Skoll via openclaw
|
Failures unrelated to PR. |
|
Retest this please Jenkins |
JacobBarthelmeh
left a comment
There was a problem hiding this comment.
This appears to be a good refactor. I need help on closer review of DTLS 1.3 changes though. @rizlik could you provide an additional review?
|
retest this please |
rizlik
left a comment
There was a problem hiding this comment.
Very nice!
Can you add a github action that install python script dependencies and run the test? My fear is that this test might be skipped because of the missing dependency and the multimessage is left untested in our CI.
3caf4b9 to
b2ab734
Compare
|
@rizlik added python setup to relevant workflows. |
|
Move padSz index advancement from individual message handlers to a single location at the end of record processing in ProcessReply. Previously, each handler (DoFinished, DoApplicationData, DoAlert, DoCertificate, DoServerHello, etc.) advanced the index by padSz, which then had to be corrected when processing multiple messages in one record. This "middle padding" pattern was error-prone. Now curSize is reduced by padSz after decryption/verification so it reflects content size only. Message handlers advance the index by content size only. padSz is added once when the record is fully processed. The correction code for multi-message records is removed.
Since ProcessReply already reduces curSize by padSz after decryption, use curStartIdx + curSize to bound content data instead of recomputing it from buffer.length - padSz. This removes three more padSz references from message processing code.
Add bounds check before computing inputLength from curStartIdx + curSize to prevent unsigned underflow if *inOutIdx ever exceeds the record content boundary.
Probe ./client -e for the supported cipher list and skip suites that aren't compiled in instead of reporting them as failures.
wolfSSL builds configured with --enable-coding=no cannot parse PEM because base64 decoding is disabled. Switch the example client's -A argument to ca-cert.der so the test works in both PEM-enabled and PEM-disabled builds.
multi-msg-record.py: auto-detect the CA cert format the wolfSSL client
build accepts (PEM or DER) from the default shown in client -? help.
OPENSSL_EXTRA-style builds need PEM; NO_CODING builds need DER.
ocsp-stapling.test: skip the external login.live.com connection unless
WOLFSSL_EXTERNAL_TEST is explicitly enabled (matches external.test /
google.test convention). Local OCSP tests still run.
ocsp-responder-openssl-interop.test: use ${TMPDIR:-/tmp} for mktemp
templates so the test works when /tmp is not writable.
The test certs are RSA; if NO_RSA is defined the client can neither load nor verify them. Detect "RSA not supported" in client -? help and exit 77 (SKIP) before tlslite-ng tries to use the RSA chain.
abd7ddf to
39642d5
Compare
Move padSz index advancement from individual message handlers to a
single location at the end of record processing in ProcessReply.
Previously, each handler (DoFinished, DoApplicationData, DoAlert,
DoCertificate, DoServerHello, etc.) advanced the index by padSz,
which then had to be corrected when processing multiple messages
in one record. This "middle padding" pattern was error-prone.
Now curSize is reduced by padSz after decryption/verification so
it reflects content size only. Message handlers advance the index
by content size only. padSz is added once when the record is fully
processed. The correction code for multi-message records is removed.