BUG/MEDIUM: h3: fix access to QCS <sd> definitely

The previous patch tried to fix access to QCS <sd> member, as the latter
is not always allocated anymore on the frontend side.

  a15f0461a016a664427f5aaad2227adcc622c882
  BUG/MEDIUM: h3: do not access QCS <sd> if not allocated

In particular, access was prevented after HEADERS parsing in case
h3_req_headers_to_htx() returned an error, which indicates that the
stream-endpoint allocation was not performed. However, this still is not
enough when QCS instance is already closed at this step. Indeed, in this
case, h3_req_headers_to_htx() returns OK but stream-endpoint allocation
is skipped as an optimization as no data exchange will be performed.

To definitely fix this kind of problems, add checks on qcs <sd> member
before accessing it in H3 layer. This method is the safest one to ensure
there is no NULL dereferencement.

This should fix github issue #3211.

This must be backported along the above mentionned patch.
This commit is contained in:
Amaury Denoyelle 2025-12-10 11:57:34 +01:00
parent 6eedd0d485
commit 5b8e6d6811

View File

@ -1784,11 +1784,8 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
if (h3_check_body_size(qcs, (fin && flen == b_data(b)))) if (h3_check_body_size(qcs, (fin && flen == b_data(b))))
break; break;
} }
else { else if (qcs->sd) {
/* content-length not present, update estimated payload length. /* content-length not present, update estimated payload length. */
* <qcs.sd> is valid here as HEADERS frame were already parsed,
* guaranteed by h3_check_frame_valid().
*/
qcs->sd->kip = h3s->data_len; qcs->sd->kip = h3s->data_len;
} }
} }
@ -1853,9 +1850,10 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
} }
/* Update estimated payload with content-length value if present. /* Update estimated payload with content-length value if present.
* <sd> must be allocated on h3_req_headers_to_htx() success. * On FE side, <sd> may be NULL on h3_req_headers_to_htx()
* error or if stream is already closed.
*/ */
if (ret >= 0 && h3s->flags & H3_SF_HAVE_CLEN) if (qcs->sd && h3s->flags & H3_SF_HAVE_CLEN)
qcs->sd->kip = h3s->body_len; qcs->sd->kip = h3s->body_len;
} }
else { else {