Drop assert in zrealloc and raise runtime error
authorStefano Babic <sbabic@denx.de>
Tue, 31 Aug 2021 12:43:12 +0000 (14:43 +0200)
committerStefano Babic <sbabic@denx.de>
Tue, 31 Aug 2021 12:59:23 +0000 (14:59 +0200)
Most assert in code are useful because they signal a real bug. However,
if allocation on the heap fails, it is a runtime error because system
gets rid of memory. This is more important on embedded systems,
and the caller process cannot exit but it should be informed with return
code and it will decide how to work on.

This drop the assert clause and add error code handling when zrealloc is
called. Because realloc does not touch the original pointer if fails, it
frees memory to avoid leaks.

Signed-off-by: Stefano Babic <sbabic@denx.de>
src/lib/comp/comp.c
src/lib/comp/zstd/zstd.c
src/lib/dl/multipart.c
src/lib/dl/range.c
src/lib/header.c
src/lib/index/index_create.c
src/lib/zck.c

index 063475c059b28044da244ec863f7cedf8e4f4197..a89846cae8967336e2fe81c40d9f7036ea9f6b27 100644 (file)
@@ -116,6 +116,10 @@ static bool comp_add_to_data(zckCtx *zck, zckComp *comp, const char *src,
     ALLOCD_BOOL(zck, src);
 
     comp->data = zrealloc(comp->data, comp->data_size + src_size);
+    if (!comp->data) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     zck_log(ZCK_LOG_DEBUG, "Adding %lu bytes to compressed buffer",
         src_size);
     memcpy(comp->data + comp->data_size, src, src_size);
index acf6582eccf38c24bd36535cea3b7a2f8f47705b..74a43fc0e41eea2f69c79f66e7c61e97b17bcdd9 100644 (file)
@@ -118,6 +118,10 @@ static ssize_t compress(zckCtx *zck, zckComp *comp, const char *src,
     ALLOCD_INT(zck, comp);
 
     comp->dc_data = zrealloc(comp->dc_data, comp->dc_data_size + src_size);
+    if (!comp->dc_data) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return -1;
+    }
 
     memcpy(comp->dc_data + comp->dc_data_size, src, src_size);
     *dst = NULL;
index 3e05e94364ef4447128e4685994d564a2dab4305..a76cecae7bffd1f99e253c65d2a95757730925ab 100644 (file)
@@ -120,6 +120,10 @@ size_t multipart_extract(zckDL *dl, char *b, size_t l) {
     /* Add new data to stored buffer */
     if(mp->buffer) {
         buf = zrealloc(mp->buffer, mp->buffer_len + l);
+        if (!buf) {
+            zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+            return 0;
+        }
         memcpy(buf + mp->buffer_len, b, l);
         l = mp->buffer_len + l;
         mp->buffer = NULL;  // No need to free, buf holds realloc'd buffer
index 3a565d758697e448015d4d61c57ee32b618b9513..5ca0bff1261d323b093e943917ede27dada54c61 100644 (file)
@@ -174,6 +174,10 @@ char PUBLIC *zck_get_range_char(zckCtx *zck, zckRange *range) {
         if(length > buf_size-loc) {
             buf_size = (int)(buf_size * 1.5);
             output = zrealloc(output, buf_size);
+            if (!output) {
+                zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+                return output;
+            }
             continue;
         }
         loc += length;
index 46f21d3b0b43ff29299c41a72b9b401acd6e0f36..29e5a78ec63cc03dc798143bd338ddef935ad0e0 100644 (file)
@@ -65,6 +65,10 @@ static bool read_optional_element(zckCtx *zck, size_t id, size_t data_size,
 static bool read_header_from_file(zckCtx *zck) {
     /* Allocate header and store any extra bytes at beginning of header */
     zck->header = zrealloc(zck->header, zck->lead_size + zck->header_length);
+    if (!zck->header) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     zck->lead_string = zck->header;
     char *header = zck->header + zck->lead_size;
     size_t loaded = 0;
@@ -269,6 +273,10 @@ static bool preface_create(zckCtx *zck) {
 
     /* Shrink header to actual size */
     header = zrealloc(header, length);
+    if (!header) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
 
     zck->preface_string = header;
     zck->preface_size = length;
@@ -321,6 +329,10 @@ static bool lead_create(zckCtx *zck) {
     length += zck->hash_type.digest_size;
 
     header = zrealloc(header, length);
+    if (!header) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
 
     zck->lead_string = header;
     zck->lead_size = length;
@@ -477,6 +489,10 @@ static bool read_lead(zckCtx *zck) {
     /* Read header digest */
     zck_log(ZCK_LOG_DEBUG, "Reading header digest");
     header = zrealloc(header, length + zck->hash_type.digest_size);
+    if (!header) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     size_t to_read = 0;
     if(lead < length + zck->hash_type.digest_size)
         to_read = length + zck->hash_type.digest_size - lead;
index c4c08c7e61329f3741c2c240f47dc832a9734892..5405f22b44f1e26c5eacfaba302fdf841505016b 100644 (file)
@@ -148,6 +148,10 @@ bool index_create(zckCtx *zck) {
     }
     /* Shrink index to actual size */
     index = zrealloc(index, index_size);
+    if (!index) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     zck->index_string = index;
     zck->index_size = index_size;
     zck_log(ZCK_LOG_DEBUG, "Generated index: %lu bytes", zck->index_size);
index 6ebce9f5a264d765a4a14b4e01638840138b2f83..2cd051277eb011a5fedb9fad0003e69d84532f50 100644 (file)
@@ -131,6 +131,12 @@ void *zmalloc(size_t size) {
 
 void *zrealloc(void *ptr, size_t size) {
     void *ret = realloc(ptr, size);
+    /*
+     * Realloc does not touch the original block if fails.
+     * Policy is to free memory and returns with error (Null)
+     */
+    if (!ret && ptr)
+        free(ptr);
     return ret;
 }