From abcd0d5cf419224d6a016b5ebee0786e96544be3 Mon Sep 17 00:00:00 2001
From: haozi007 <liuhao27@huawei.com>
Date: Wed, 23 Aug 2023 15:42:42 +0800
Subject: [PATCH 09/10] [image] ensure id of loaded and pulled image is valid

Signed-off-by: haozi007 <liuhao27@huawei.com>
---
 src/daemon/modules/image/oci/oci_import.c     | 14 ++++++++++---
 src/daemon/modules/image/oci/oci_load.c       | 21 ++++++-------------
 .../modules/image/oci/registry/registry.c     |  8 ++++++-
 src/daemon/modules/image/oci/utils_images.c   | 15 +++++++++++++
 src/daemon/modules/image/oci/utils_images.h   |  3 +++
 src/utils/cutils/utils.h                      |  2 --
 src/utils/sha256/sha256.c                     |  1 -
 7 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/src/daemon/modules/image/oci/oci_import.c b/src/daemon/modules/image/oci/oci_import.c
index 335ee8d4..b261188d 100644
--- a/src/daemon/modules/image/oci/oci_import.c
+++ b/src/daemon/modules/image/oci/oci_import.c
@@ -97,7 +97,7 @@ static int register_layer(import_desc *desc)
         return -1;
     }
 
-    id = util_without_sha256_prefix(desc->uncompressed_digest);
+    id = oci_image_id_from_digest(desc->uncompressed_digest);
     if (id == NULL) {
         ERROR("Invalid NULL param");
         return -1;
@@ -318,8 +318,16 @@ static int register_image(import_desc *desc)
     opts.create_time = &desc->now_time;
     opts.digest = desc->manifest_digest;
 
-    image_id = util_without_sha256_prefix(desc->config_digest);
-    top_layer_id = util_without_sha256_prefix(desc->uncompressed_digest);
+    image_id = oci_image_id_from_digest(desc->config_digest);
+    if (image_id == NULL) {
+        ret = -1;
+        goto out;
+    }
+    top_layer_id = oci_image_id_from_digest(desc->uncompressed_digest);
+    if (top_layer_id == NULL) {
+        ret = -1;
+        goto out;
+    }
     ret = storage_img_create(image_id, top_layer_id, NULL, &opts);
     if (ret != 0) {
         pre_top_layer = storage_get_img_top_layer(image_id);
diff --git a/src/daemon/modules/image/oci/oci_load.c b/src/daemon/modules/image/oci/oci_load.c
index 64ef2a1a..01b9ef6e 100644
--- a/src/daemon/modules/image/oci/oci_load.c
+++ b/src/daemon/modules/image/oci/oci_load.c
@@ -283,16 +283,6 @@ out:
     return full_digest;
 }
 
-static char *oci_load_without_sha256_prefix(char *digest)
-{
-    if (digest == NULL) {
-        ERROR("Invalid digest NULL when strip sha256 prefix");
-        return NULL;
-    }
-
-    return digest + strlen(SHA256_PREFIX);
-}
-
 static int registry_layer_from_tarball(const load_layer_blob_t *layer, const char *id, const char *parent)
 {
     int ret = 0;
@@ -338,7 +328,7 @@ static int oci_load_register_layers(load_image_t *desc)
     }
 
     for (i = 0; i < desc->layers_len; i++) {
-        id = oci_load_without_sha256_prefix(desc->layers[i]->chain_id);
+        id = oci_image_id_from_digest(desc->layers[i]->chain_id);
         if (id == NULL) {
             ERROR("layer %zu have NULL digest for image %s", i, desc->im_id);
             ret = -1;
@@ -450,7 +440,7 @@ static int oci_load_create_image(load_image_t *desc, const char *dst_tag)
     top_layer_index = desc->layers_len - 1;
     opts.create_time = &timestamp;
     opts.digest = desc->manifest_digest;
-    top_layer_id = oci_load_without_sha256_prefix(desc->layers[top_layer_index]->chain_id);
+    top_layer_id = oci_image_id_from_digest(desc->layers[top_layer_index]->chain_id);
     if (top_layer_id == NULL) {
         ERROR("NULL top layer id found for image %s", desc->im_id);
         ret = -1;
@@ -735,7 +725,7 @@ static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items
         }
         parent_chain_id_sha256 = im->layers[i]->chain_id;
 
-        id = oci_load_without_sha256_prefix(im->layers[i]->chain_id);
+        id = oci_image_id_from_digest(im->layers[i]->chain_id);
         if (id == NULL) {
             ERROR("Wipe out sha256 prefix failed from layer with chain id : %s", im->layers[i]->chain_id);
             ret = -1;
@@ -803,7 +793,8 @@ static load_image_t *oci_load_process_manifest(const image_manifest_items_elemen
         goto out;
     }
 
-    image_id = oci_load_without_sha256_prefix(image_digest);
+    // call util_valid_digest to ensure digest is valid, so image id is valid
+    image_id = oci_image_id_from_digest(image_digest);
     if (image_id == NULL) {
         ret = -1;
         ERROR("Remove sha256 prefix error from image digest %s", image_digest);
@@ -843,7 +834,7 @@ static int64_t get_layer_size_from_storage(char *chain_id_pre)
         return -1;
     }
 
-    id = oci_load_without_sha256_prefix(chain_id_pre);
+    id = oci_image_id_from_digest(chain_id_pre);
     if (id == NULL) {
         ERROR("Get chain id failed from value:%s", chain_id_pre);
         size = -1;
diff --git a/src/daemon/modules/image/oci/registry/registry.c b/src/daemon/modules/image/oci/registry/registry.c
index 14e84f81..402863a0 100644
--- a/src/daemon/modules/image/oci/registry/registry.c
+++ b/src/daemon/modules/image/oci/registry/registry.c
@@ -869,7 +869,13 @@ static int register_image(pull_descriptor *desc)
 
     // lock when create image to make sure image content all exist
     mutex_lock(&g_shared->image_mutex);
-    image_id = util_without_sha256_prefix(desc->config.digest);
+    image_id = oci_image_id_from_digest(desc->config.digest);
+    if (image_id == NULL) {
+        ERROR("Invalid digest: %s", desc->config.digest);
+        isulad_try_set_error_message("invalid image digest: %s", desc->config.digest);
+        ret = -1;
+        goto out;
+    }
     ret = create_image(desc, image_id, &reuse);
     if (ret != 0) {
         ERROR("create image %s failed", desc->image_name);
diff --git a/src/daemon/modules/image/oci/utils_images.c b/src/daemon/modules/image/oci/utils_images.c
index 794f0d16..6acbbb12 100644
--- a/src/daemon/modules/image/oci/utils_images.c
+++ b/src/daemon/modules/image/oci/utils_images.c
@@ -639,3 +639,18 @@ out:
 
     return ret;
 }
+
+char *oci_image_id_from_digest(char *digest)
+{
+    if (digest == NULL) {
+        ERROR("Empty digest");
+        return NULL;
+    }
+
+    if (!util_valid_digest(digest)) {
+        ERROR("Load image with invalid digest: %s", digest);
+        return NULL;
+    }
+
+    return digest + strlen(SHA256_PREFIX);
+}
diff --git a/src/daemon/modules/image/oci/utils_images.h b/src/daemon/modules/image/oci/utils_images.h
index 53bce4e0..86c1b2a7 100644
--- a/src/daemon/modules/image/oci/utils_images.h
+++ b/src/daemon/modules/image/oci/utils_images.h
@@ -58,6 +58,9 @@ char *get_hostname_to_strip();
 
 char *oci_image_digest_pos(const char *name);
 
+// return a pointer to digest string without 'sha256:' prefix
+char *oci_image_id_from_digest(char *digest);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/utils/cutils/utils.h b/src/utils/cutils/utils.h
index 8489ca63..bb510062 100644
--- a/src/utils/cutils/utils.h
+++ b/src/utils/cutils/utils.h
@@ -379,8 +379,6 @@ int util_generate_random_str(char *id, size_t len);
 
 int util_check_inherited_exclude_fds(bool closeall, int *fds_to_ignore, size_t len_fds);
 
-char *util_without_sha256_prefix(char *digest);
-
 int util_normalized_host_os_arch(char **host_os, char **host_arch, char **host_variant);
 
 int util_read_pid_ppid_info(uint32_t pid, pid_ppid_info_t *pid_info);
diff --git a/src/utils/sha256/sha256.c b/src/utils/sha256/sha256.c
index 938e3692..81375111 100644
--- a/src/utils/sha256/sha256.c
+++ b/src/utils/sha256/sha256.c
@@ -390,7 +390,6 @@ char *sha256_full_digest_str(char *str)
 char *util_without_sha256_prefix(char *digest)
 {
     if (digest == NULL || !util_has_prefix(digest, SHA256_PREFIX)) {
-        ERROR("Invalid digest when strip sha256 prefix");
         return NULL;
     }
 
-- 
2.25.1

