From: Hugo Landau Date: Wed, 30 Aug 2023 09:32:53 +0000 (+0100) Subject: QUIC: Harden ring buffer against internal misuse X-Git-Tag: openssl-3.2.0-alpha1~104 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60421893a286bb9eb7fb7c2454b84af9778ffca4;p=thirdparty%2Fopenssl.git QUIC: Harden ring buffer against internal misuse Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/21895) --- diff --git a/include/internal/ring_buf.h b/include/internal/ring_buf.h index 1d70439278b..85a8d309bae 100644 --- a/include/internal/ring_buf.h +++ b/include/internal/ring_buf.h @@ -12,6 +12,7 @@ # pragma once # include /* For 'ossl_inline' */ +# include "internal/safe_math.h" /* * ================================================================== @@ -39,6 +40,10 @@ struct ring_buf { uint64_t ctail_offset; }; +OSSL_SAFE_MATH_UNSIGNED(u64, uint64_t) + +#define MAX_OFFSET (((uint64_t)1) << 62) /* QUIC-imposed limit */ + static ossl_inline int ring_buf_init(struct ring_buf *r) { r->start = NULL; @@ -74,11 +79,15 @@ static ossl_inline int ring_buf_write_at(struct ring_buf *r, { size_t avail, idx, l; unsigned char *start = r->start; - int i; + int i, err = 0; avail = ring_buf_avail(r); if (logical_offset < r->ctail_offset - || logical_offset + buf_len > r->head_offset + avail) + || safe_add_u64(logical_offset, buf_len, &err) + > safe_add_u64(r->head_offset, avail, &err) + || safe_add_u64(r->head_offset, buf_len, &err) + > MAX_OFFSET + || err) return 0; for (i = 0; buf_len > 0 && i < 2; ++i) { @@ -113,6 +122,9 @@ static ossl_inline size_t ring_buf_push(struct ring_buf *r, if (buf_len > avail) buf_len = avail; + if (buf_len > MAX_OFFSET - r->head_offset) + buf_len = (size_t)(MAX_OFFSET - r->head_offset); + if (buf_len == 0) break; @@ -190,7 +202,7 @@ static ossl_inline void ring_buf_cpop_range(struct ring_buf *r, { assert(end >= start); - if (start > r->ctail_offset) + if (start > r->ctail_offset || end >= MAX_OFFSET) return; if (cleanse && r->alloc > 0 && end > r->ctail_offset) {