From: Victor Julien Date: Tue, 13 Jun 2023 09:56:17 +0000 (+0200) Subject: streaming/buffer: set errno in allocators X-Git-Tag: suricata-7.0.0-rc2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b5da30d9d1b3f655c246eb0cbdf0731af9432f4;p=thirdparty%2Fsuricata.git streaming/buffer: set errno in allocators Add wrappers for the default allocators to set SC_ENOMEM. The stream reassembly wrappers can set both SC_ENOMEM (alloc failed) and SC_ELIMIT (memcap reached). --- diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 21d74dd1c3..90bac3c649 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -208,11 +208,15 @@ uint64_t StreamTcpReassembleGetMemcap(void) */ static void *ReassembleCalloc(size_t n, size_t size) { - if (StreamTcpReassembleCheckMemcap(n * size) == 0) + if (StreamTcpReassembleCheckMemcap(n * size) == 0) { + sc_errno = SC_ELIMIT; return NULL; + } void *ptr = SCCalloc(n, size); - if (ptr == NULL) + if (ptr == NULL) { + sc_errno = SC_ENOMEM; return NULL; + } StreamTcpReassembleIncrMemuse(n * size); return ptr; } @@ -225,12 +229,14 @@ void *StreamTcpReassembleRealloc(void *optr, size_t orig_size, size_t size) if (size > orig_size) { if (StreamTcpReassembleCheckMemcap(size - orig_size) == 0) { SCLogDebug("memcap hit at %" PRIu64, SC_ATOMIC_GET(stream_config.reassembly_memcap)); + sc_errno = SC_ELIMIT; return NULL; } } void *nptr = SCRealloc(optr, size); if (nptr == NULL) { SCLogDebug("realloc fail"); + sc_errno = SC_ENOMEM; return NULL; } if (size > orig_size) { diff --git a/src/util-streaming-buffer.c b/src/util-streaming-buffer.c index fe6b9f70f1..7608b50821 100644 --- a/src/util-streaming-buffer.c +++ b/src/util-streaming-buffer.c @@ -35,12 +35,30 @@ static void ListRegions(StreamingBuffer *sb); * \brief Streaming Buffer API */ +static void *ReallocFunc(void *ptr, const size_t size) +{ + void *ptrmem = SCRealloc(ptr, size); + if (unlikely(ptrmem == NULL)) { + sc_errno = SC_ENOMEM; + } + return ptrmem; +} + +static void *CallocFunc(const size_t nm, const size_t sz) +{ + void *ptrmem = SCCalloc(nm, sz); + if (unlikely(ptrmem == NULL)) { + sc_errno = SC_ENOMEM; + } + return ptrmem; +} + /* memory handling wrappers. If config doesn't define it's own set of * functions, use the defaults */ -#define CALLOC(cfg, n, s) \ - (cfg)->Calloc ? (cfg)->Calloc((n), (s)) : SCCalloc((n), (s)) -#define REALLOC(cfg, ptr, orig_s, s) \ - (cfg)->Realloc ? (cfg)->Realloc((ptr), (orig_s), (s)) : SCRealloc((ptr), (s)) +// TODO the default allocators don't set `sc_errno` yet. +#define CALLOC(cfg, n, s) (cfg)->Calloc ? (cfg)->Calloc((n), (s)) : CallocFunc((n), (s)) +#define REALLOC(cfg, ptr, orig_s, s) \ + (cfg)->Realloc ? (cfg)->Realloc((ptr), (orig_s), (s)) : ReallocFunc((ptr), (s)) #define FREE(cfg, ptr, s) \ (cfg)->Free ? (cfg)->Free((ptr), (s)) : SCFree((ptr)) @@ -204,14 +222,12 @@ static inline StreamingBufferRegion *InitBufferRegion( StreamingBufferRegion *aux_r = CALLOC(cfg, 1, sizeof(*aux_r)); if (aux_r == NULL) { - sc_errno = SC_ENOMEM; return NULL; } aux_r->buf = CALLOC(cfg, 1, MAX(cfg->buf_size, min_size)); if (aux_r->buf == NULL) { FREE(cfg, aux_r, sizeof(*aux_r)); - sc_errno = SC_ENOMEM; return NULL; } aux_r->buf_size = MAX(cfg->buf_size, min_size); @@ -224,7 +240,7 @@ static inline int InitBuffer(StreamingBuffer *sb, const StreamingBufferConfig *c { sb->region.buf = CALLOC(cfg, 1, cfg->buf_size); if (sb->region.buf == NULL) { - return SC_ENOMEM; + return sc_errno; } sb->region.buf_size = cfg->buf_size; return SC_OK; @@ -234,7 +250,6 @@ StreamingBuffer *StreamingBufferInit(const StreamingBufferConfig *cfg) { StreamingBuffer *sb = CALLOC(cfg, 1, sizeof(StreamingBuffer)); if (sb == NULL) { - sc_errno = SC_ENOMEM; return NULL; } @@ -315,7 +330,7 @@ static int WARN_UNUSED SBBInit(StreamingBuffer *sb, const StreamingBufferConfig /* need to set up 2: existing data block and new data block */ StreamingBufferBlock *sbb = CALLOC(cfg, 1, sizeof(*sbb)); if (sbb == NULL) { - return SC_ENOMEM; + return sc_errno; } sbb->offset = sb->region.stream_offset; sbb->len = sb->region.buf_offset; @@ -325,7 +340,7 @@ static int WARN_UNUSED SBBInit(StreamingBuffer *sb, const StreamingBufferConfig StreamingBufferBlock *sbb2 = CALLOC(cfg, 1, sizeof(*sbb2)); if (sbb2 == NULL) { - return SC_ENOMEM; + return sc_errno; } sbb2->offset = region->stream_offset + rel_offset; sbb2->len = data_len; @@ -356,7 +371,7 @@ static int WARN_UNUSED SBBInitLeadingGap(StreamingBuffer *sb, const StreamingBuf StreamingBufferBlock *sbb = CALLOC(cfg, 1, sizeof(*sbb)); if (sbb == NULL) { - return SC_ENOMEM; + return sc_errno; } sbb->offset = offset; sbb->len = data_len; @@ -577,7 +592,7 @@ static int SBBUpdate(StreamingBuffer *sb, const StreamingBufferConfig *cfg, StreamingBufferBlock *sbb = CALLOC(cfg, 1, sizeof(*sbb)); if (sbb == NULL) { - return SC_ENOMEM; + return sc_errno; } sbb->offset = region->stream_offset + rel_offset; sbb->len = len; @@ -706,7 +721,7 @@ static inline int WARN_UNUSED GrowRegionToSize(StreamingBuffer *sb, void *ptr = REALLOC(cfg, region->buf, region->buf_size, grow); if (ptr == NULL) { - return SC_ENOMEM; + return sc_errno; } /* for safe printing and general caution, lets memset the * new data to 0 */