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