DTLS handshake reassembly heap out-of-bounds write via sequence-agnostic fragment merge
## Description of problem: GnuTLS DTLS handshake fragment reassembly matches existing reassembly entries using only the handshake message type (`htype`), while ignoring the DTLS handshake `sequence` field. The relevant behavior is: * DTLS handshake headers are parsed and the `sequence` field is extracted * `merge_handshake_packet()` then searches for an existing reassembly entry using only `htype` * if a match is found, the incoming fragment is merged into the existing reassembly buffer * the merge path performs `memcpy()` into the existing buffer without checking that `start_offset + fragment_length` fits within the capacity allocated for that buffer This means that fragments from two different DTLS handshake messages can be merged into the same reassembly buffer as long as they share the same handshake type. One concrete case is: * the first fragment uses handshake type `T`, sequence `0`, declared message length `100`, and fragment range `0..49` * because it is the first fragment for that type, GnuTLS allocates a reassembly buffer sized for length `100` * a second fragment then uses the same handshake type `T`, but sequence `1`, declared message length `200`, and fragment range `50..199` * because lookup is based only on `htype`, GnuTLS merges the second fragment into the first message's buffer * the merge path copies `150` bytes at offset `50` into a buffer allocated for only `100` bytes This produces a heap out-of-bounds write in the DTLS handshake reassembly path. The `sequence` field is used later for sorting and message ordering, but not when selecting the reassembly slot. Therefore the wrong merge occurs before any sequence-based ordering logic can prevent it. ## Version of gnutls used: 3.8.12-73-g8b6731064-dirty ## Distributor of gnutls (e.g., Ubuntu, Fedora, RHEL) Not distributor-specific in this report. Analysis is based on the local upstream source tree in `/workspace/gnutls`. ## How reproducible: Steps to Reproduce: * Inspect the DTLS handshake parsing path and confirm that the handshake `sequence` field is parsed from the DTLS header. * Inspect `merge_handshake_packet()` and confirm that the reassembly lookup compares only `htype`, not `sequence`. * Confirm that in the merge path GnuTLS copies fragment data into the existing reassembly buffer without checking that the write fits within the buffer originally allocated for the first fragment. ## Actual results: Fragments from different DTLS handshake messages that share the same handshake type can be merged into the same reassembly buffer. If the first fragment caused allocation of a smaller buffer, and a later fragment from a different `sequence` uses a larger declared message length and an overlapping offset range, the merge path can write beyond the end of the heap allocation. I also prepared a small validation harness for the core logic, which shows the second fragment overwriting bytes past the end of the first fragment's buffer. ## Expected results: DTLS handshake fragment reassembly should match fragments using both handshake type and handshake `sequence`, so fragments belonging to different DTLS handshake messages are never merged into the same buffer. In addition, the merge path should reject any fragment for which `start_offset + fragment_length` exceeds the capacity of the target reassembly buffer.
issue