From 1530d542f0beaf9aca8eee68096996240a755b1c Mon Sep 17 00:00:00 2001
From: haozi007 <liuhao27@huawei.com>
Date: Tue, 16 Aug 2022 19:50:29 +0800
Subject: [PATCH 21/21] [clang-analyzer] fix memory leak and use after free

Signed-off-by: haozi007 <liuhao27@huawei.com>
---
 .../connect/grpc/grpc_containers_client.cc    |  5 +++++
 .../entry/cri/websocket/service/ws_server.cc  |  1 +
 .../oci/storage/layer_store/layer_store.c     | 21 +++++++++----------
 src/utils/cpputils/url.cc                     |  2 +-
 src/utils/cutils/utils_file.c                 |  2 +-
 5 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/client/connect/grpc/grpc_containers_client.cc b/src/client/connect/grpc/grpc_containers_client.cc
index 85cafe9b..33c7c631 100644
--- a/src/client/connect/grpc/grpc_containers_client.cc
+++ b/src/client/connect/grpc/grpc_containers_client.cc
@@ -1926,6 +1926,7 @@ public:
                                             ClientBaseConstants::COMMON_NAME_LEN);
         if (ret != 0) {
             ERROR("Failed to get common name in: %s", m_certFile.c_str());
+            delete ctx;
             return -1;
         }
         ctx->context.AddMetadata("username", std::string(common_name_value, strlen(common_name_value)));
@@ -1945,11 +1946,15 @@ public:
                 ERROR("Invalid json: %s", err);
                 free(err);
                 CopyFromContainerFinish(ctx, &response->errmsg);
+                delete ctx->reader;
+                delete ctx;
                 return -1;
             }
             free(err);
         } else {
             CopyFromContainerFinish(ctx, &response->errmsg);
+            delete ctx->reader;
+            delete ctx;
             return -1;
         }
         // Ignore the first reader which is used for transform metadata
diff --git a/src/daemon/entry/cri/websocket/service/ws_server.cc b/src/daemon/entry/cri/websocket/service/ws_server.cc
index 08f2cff0..63afc9dd 100644
--- a/src/daemon/entry/cri/websocket/service/ws_server.cc
+++ b/src/daemon/entry/cri/websocket/service/ws_server.cc
@@ -391,6 +391,7 @@ int WebsocketServer::RegisterStreamTask(struct lws *wsi) noexcept
     }
     if (GenerateSessionData(session, containerID) != 0) {
         ERROR("failed to fill generate session data");
+        delete session;
         return -1;
     }
 
diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c
index cd18c6aa..e563a8ef 100644
--- a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c
+++ b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c
@@ -853,7 +853,7 @@ static void free_storage_entry_data(storage_entry *entry)
     }
 }
 
-static char *caculate_playload(struct archive *ar)
+static int caculate_playload(struct archive *ar, char **result)
 {
     int r = 0;
     unsigned char *block_buf = NULL;
@@ -863,8 +863,7 @@ static char *caculate_playload(struct archive *ar)
 #else
     off_t block_offset = 0;
 #endif
-    char *ret = NULL;
-    int nret = 0;
+    int ret = 0;
     const isula_crc_table_t *ctab = NULL;
     uint64_t crc = 0;
     // max crc bits is 8
@@ -876,7 +875,7 @@ static char *caculate_playload(struct archive *ar)
     ctab = new_isula_crc_table(ISO_POLY);
 
     if (ctab == NULL) {
-        return NULL;
+        return -1;
     }
 
     for (;;) {
@@ -886,10 +885,12 @@ static char *caculate_playload(struct archive *ar)
         }
         if (r != ARCHIVE_OK) {
             ERROR("Read archive failed");
+            ret = -1;
             goto out;
         }
         if (!isula_crc_update(ctab, &crc, block_buf, block_size)) {
             ERROR("Do crc update failed");
+            ret = -1;
             goto out;
         }
         empty = false;
@@ -903,10 +904,9 @@ static char *caculate_playload(struct archive *ar)
     for (r = 0; r < 8; r++) {
         tmp_data[r] = sum_data[r];
     }
-    nret = util_base64_encode(tmp_data, 8, &ret);
-
-    if (nret != 0) {
-        return NULL;
+    ret = util_base64_encode(tmp_data, 8, result);
+    if (ret != 0) {
+        ERROR("Do encode failed");
     }
 
 out:
@@ -929,9 +929,8 @@ static int archive_entry_parse(struct archive_entry *entry, struct archive *ar,
     sentry.size = archive_entry_size(entry);
     sentry.position = position;
     // caculate playload
-    sentry.payload = caculate_playload(ar);
-    if (sentry.payload == NULL) {
-        ERROR("Caculate playload failed.");
+    if (caculate_playload(ar, &sentry.payload) != 0) {
+        ERROR("Caculate playload failed");
         goto out;
     }
 
diff --git a/src/utils/cpputils/url.cc b/src/utils/cpputils/url.cc
index ab1355a3..c78cf787 100644
--- a/src/utils/cpputils/url.cc
+++ b/src/utils/cpputils/url.cc
@@ -32,7 +32,7 @@ bool GetHexDigit(char c, char &d)
         d = c - '0';
     } else if (c >= 'a' && c <= 'f') {
         d = c - 'a' + 10;
-    } else if (c >= 'A' && c <= 'F') {
+    } else {
         d = c - 'A' + 10;
     }
     return true;
diff --git a/src/utils/cutils/utils_file.c b/src/utils/cutils/utils_file.c
index 67e7a707..f06f4d49 100644
--- a/src/utils/cutils/utils_file.c
+++ b/src/utils/cutils/utils_file.c
@@ -1549,10 +1549,10 @@ int util_atomic_write_file(const char *fname, const char *content, size_t conten
     }
 
 free_out:
-    free(tmp_file);
     if (ret != 0 && unlink(tmp_file) != 0 && errno != ENOENT) {
         SYSERROR("Failed to remove temp file:%s", tmp_file);
     }
+    free(tmp_file);
     return ret;
 }
 
-- 
2.25.1

