# pragma once
# include <openssl/e_os2.h> /* For 'ossl_inline' */
+# include "internal/safe_math.h"
/*
* ==================================================================
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;
{
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) {
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;
{
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) {