]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
streaming/buffer: set errno in allocators 9021/head
authorVictor Julien <vjulien@oisf.net>
Tue, 13 Jun 2023 09:56:17 +0000 (11:56 +0200)
committerVictor Julien <vjulien@oisf.net>
Tue, 13 Jun 2023 11:12:14 +0000 (13:12 +0200)
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).

src/stream-tcp-reassemble.c
src/util-streaming-buffer.c

index 21d74dd1c3ab542ef6cf407e821f41c80fec7bd0..90bac3c649497b0d60094259f7e92f83f841c89a 100644 (file)
@@ -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) {
index fe6b9f70f177fb268cebf113e9fbb040ef94ff8b..7608b5082109caa68e6b6161a8e703c44d232192 100644 (file)
@@ -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 */