A QCS instance must only be closed remotely once. A BUG_ON() enforces
it, so that FIN signalling to the upper layer is correct.
There exists a possible case of a double remote closure after data
transfer between two adjacent buffers on parser blocking. This only
happens if the next buffer is emptied and a standalone FIN is then
received. First qcs_close_remote() will be called during the empty
STREAM FIN reception. This is called again on qcc_decode_qcs() after
consuming data when dealing with the empty remaining buffer.
This patch fixes this by preventing the second call to
qcs_close_remote() in case an empty buffer is detected.
This bug is not easily reproducible as it is highly dependent on the
precise order of these different operations.
This must be backported up to 3.2, as this is the first release which
support multiple QCS Rx buffers.
*/
if (qcs->flags & QC_SF_SIZE_KNOWN && !eb_is_empty(&qcs->rx.bufs)) {
const ncb_sz_t avail = qcs_rx_avail_data(qcs);
- if (qcs->rx.offset + avail == qcs->rx.offset_max)
+
+ /* A remotely closed QCS cannot have a non empty Rx buffer left to parse. */
+ BUG_ON(avail && qcs_is_close_remote(qcs));
+
+ /* <avail> null check ensures an empty buffer is ignored. */
+ if (avail && qcs->rx.offset + avail == qcs->rx.offset_max)
qcs_close_remote(qcs);
}
}