summaryrefslogtreecommitdiff
path: root/0062-verify-name-and-digest-consistency.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-01-20 09:57:05 +0000
committerCoprDistGit <infra@openeuler.org>2024-01-20 09:57:05 +0000
commitc56563a5cfb85fcba9f28dd1df9647037eb2931e (patch)
tree82e936c48ac53d5a05ac395f897e421a743f8023 /0062-verify-name-and-digest-consistency.patch
parent8c7a257a80c20ee3fae444f9e3d670a86dca161f (diff)
automatic import of iSuladopeneuler23.09openeuler22.03_LTS_SP2
Diffstat (limited to '0062-verify-name-and-digest-consistency.patch')
-rw-r--r--0062-verify-name-and-digest-consistency.patch319
1 files changed, 319 insertions, 0 deletions
diff --git a/0062-verify-name-and-digest-consistency.patch b/0062-verify-name-and-digest-consistency.patch
new file mode 100644
index 0000000..e56bbd7
--- /dev/null
+++ b/0062-verify-name-and-digest-consistency.patch
@@ -0,0 +1,319 @@
+From 950dc3c56f192061383de4d19229ace243eae503 Mon Sep 17 00:00:00 2001
+From: zhongtao <zhongtao17@huawei.com>
+Date: Mon, 18 Dec 2023 15:54:37 +0800
+Subject: [PATCH 62/64] verify name and digest consistency
+
+Signed-off-by: zhongtao <zhongtao17@huawei.com>
+---
+ .../oci/storage/image_store/image_store.c | 265 +++++++++++-------
+ 1 file changed, 162 insertions(+), 103 deletions(-)
+
+diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.c b/src/daemon/modules/image/oci/storage/image_store/image_store.c
+index 58baa47a..1b482504 100644
+--- a/src/daemon/modules/image/oci/storage/image_store/image_store.c
++++ b/src/daemon/modules/image/oci/storage/image_store/image_store.c
+@@ -22,6 +22,7 @@
+ #include <isula_libutils/storage_image.h>
+ #include <isula_libutils/imagetool_images_list.h>
+ #include <isula_libutils/json_common.h>
++#include <isula_libutils/auto_cleanup.h>
+ #include <limits.h>
+ #include <pthread.h>
+ #include <stdlib.h>
+@@ -444,11 +445,161 @@ out:
+ return value;
+ }
+
++static int resort_image_names(const char **names, size_t names_len, char **first_name, char ***image_tags,
++ char ***image_digests)
++{
++ int ret = 0;
++ size_t i;
++ char *prefix = NULL;
++
++ for (i = 0; i < names_len; i++) {
++ size_t len = strlen(names[i]);
++ if (strlen(names[i]) > MAX_IMAGE_NAME_LENGTH) {
++ prefix = util_sub_string(names[i], len - MAX_IMAGE_NAME_LENGTH,
++ MAX_IMAGE_NAME_LENGTH - MAX_IMAGE_DIGEST_LENGTH);
++ }
++
++ // TODO: maybe should support other digest
++ if (prefix != NULL && strcmp(prefix, DIGEST_PREFIX) == 0) {
++ if (util_array_append(image_digests, names[i]) != 0) {
++ ERROR("Failed to append image to digest: %s", names[i]);
++ ret = -1;
++ goto out;
++ }
++ } else {
++ if (util_array_append(image_tags, names[i]) != 0) {
++ ERROR("Failed to append image to tags: %s", names[i]);
++ ret = -1;
++ goto out;
++ }
++ }
++ }
++
++ if (first_name == NULL) {
++ goto out;
++ }
++
++ if (util_array_len((const char **)(*image_digests)) > 0) {
++ free(*first_name);
++ *first_name = util_strdup_s((*image_digests)[0]);
++ }
++
++ if (util_array_len((const char **)(*image_tags)) > 0) {
++ free(*first_name);
++ *first_name = util_strdup_s((*image_tags)[0]);
++ }
++
++out:
++ if (ret != 0) {
++ util_free_array(*image_digests);
++ util_free_array(*image_tags);
++ free(*first_name);
++ }
++ free(prefix);
++ return ret;
++}
++
++// Validate checks that the contents is a valid digest
++static bool validate_digest(const char *digest)
++{
++ bool ret = true;
++ const char *sha256_encode_patten = "^[a-f0-9]{64}$";
++ char *value = util_strdup_s(digest);
++ char *index = strchr(value, ':');
++ char *alg = NULL;
++ char *encode = NULL;
++
++ // contains ':' and is not the last character
++ if (index == NULL || index - value + 1 == strlen(value)) {
++ INFO("Invalid checksum digest format");
++ ret = false;
++ goto out;
++ }
++
++ *index++ = '\0';
++
++ alg = value;
++ encode = index;
++ // Currently only support SHA256 algorithm
++ if (strcmp(alg, "sha256") != 0) {
++ DEBUG("Unsupported digest algorithm: %s", alg);
++ ret = false;
++ goto out;
++ }
++
++ ret = util_reg_match(sha256_encode_patten, encode) == 0;
++
++out:
++ free(value);
++ return ret;
++}
++
++// Parsing a reference string as a possible identifier, full digest, or familiar name.
++static char *parse_digest_reference(const char *ref)
++{
++ char *indentfier_patten = "^[a-f0-9]{64}$";
++
++ if (util_reg_match(indentfier_patten, ref) == 0) {
++ return util_string_append(ref, "sha256:");
++ }
++
++ if (validate_digest(ref)) {
++ return util_strdup_s(ref);
++ }
++
++ return oci_normalize_image_name(ref);
++}
++
++static int is_name_digest_consistent(const char *name, char **names, size_t names_len, const char *digest)
++{
++ size_t i;
++ int ret = -1;
++ int nret = 0;
++ char *tag_pos = NULL;
++ char **tags = NULL;
++ char **digests = NULL;
++
++ if (resort_image_names((const char **)names, names_len, NULL, &tags, &digests) != 0) {
++ ERROR("Failed to resort image names");
++ goto out;
++ }
++
++ for (i = 0; i < util_array_len((const char **)tags); i++) {
++ __isula_auto_free char *ref = NULL;
++ __isula_auto_free char *tmp_repo_digests = NULL;
++ ref = parse_digest_reference(tags[i]);
++ if (ref == NULL) {
++ continue;
++ }
++ tag_pos = util_tag_pos(ref);
++ if (tag_pos == NULL) {
++ ERROR("invalid ref %s", ref);
++ continue;
++ }
++ *tag_pos = '\0';
++
++ nret = asprintf(&tmp_repo_digests, "%s@%s", ref, digest);
++ if (nret < 0) {
++ ERROR("Failed to receive repo digest");
++ goto out;
++ }
++ if (strcmp(name, tmp_repo_digests) == 0) {
++ ret = 0;
++ goto out;
++ }
++ }
++out:
++ util_free_array(tags);
++ util_free_array(digests);
++ return ret;
++}
++
+ // by_digest returns the image which matches the specified name.
+ static image_t *by_digest(const char *name)
+ {
+ digest_image_t *digest_filter_images = NULL;
+ char *digest = NULL;
++ image_t *tmp_ret = NULL;
+
+ // split digest for image name with digest
+ digest = strrchr(name, '@');
+@@ -457,12 +608,21 @@ static image_t *by_digest(const char *name)
+ }
+ digest++;
+ digest_filter_images = (digest_image_t *)map_search(g_image_store->bydigest, (void *)digest);
+- if (digest_filter_images == NULL) {
++ if (digest_filter_images == NULL || linked_list_empty(&(digest_filter_images->images_list))) {
+ return NULL;
+ }
+
+ // currently, a digest corresponds to an image, directly returning the first element
+- return linked_list_first_elem(&(digest_filter_images->images_list));
++ tmp_ret = linked_list_first_elem(&(digest_filter_images->images_list));
++
++ // verify name and digest consistency to ensure we are not matching images to different repositories,
++ // even if the digests match.
++ // For example, ubuntu@sha256:abc......, shouldn't match test@sha256:abc......
++ if (is_name_digest_consistent(name, tmp_ret->simage->names, tmp_ret->simage->names_len, digest) != 0) {
++ return NULL;
++ }
++
++ return tmp_ret;
+ }
+
+ static image_t *lookup(const char *id)
+@@ -2001,107 +2161,6 @@ out:
+ return ret;
+ }
+
+-static int resort_image_names(const char **names, size_t names_len, char **first_name, char ***image_tags,
+- char ***image_digests)
+-{
+- int ret = 0;
+- size_t i;
+- char *prefix = NULL;
+-
+- for (i = 0; i < names_len; i++) {
+- size_t len = strlen(names[i]);
+- if (strlen(names[i]) > MAX_IMAGE_NAME_LENGTH) {
+- prefix = util_sub_string(names[i], len - MAX_IMAGE_NAME_LENGTH,
+- MAX_IMAGE_NAME_LENGTH - MAX_IMAGE_DIGEST_LENGTH);
+- }
+-
+- // TODO: maybe should support other digest
+- if (prefix != NULL && strcmp(prefix, DIGEST_PREFIX) == 0) {
+- if (util_array_append(image_digests, names[i]) != 0) {
+- ERROR("Failed to append image to digest: %s", names[i]);
+- ret = -1;
+- goto out;
+- }
+- } else {
+- if (util_array_append(image_tags, names[i]) != 0) {
+- ERROR("Failed to append image to tags: %s", names[i]);
+- ret = -1;
+- goto out;
+- }
+- }
+- }
+-
+- if (util_array_len((const char **)(*image_digests)) > 0) {
+- free(*first_name);
+- *first_name = util_strdup_s((*image_digests)[0]);
+- }
+-
+- if (util_array_len((const char **)(*image_tags)) > 0) {
+- free(*first_name);
+- *first_name = util_strdup_s((*image_tags)[0]);
+- }
+-
+-out:
+- if (ret != 0) {
+- util_free_array(*image_digests);
+- util_free_array(*image_tags);
+- free(*first_name);
+- }
+- free(prefix);
+- return ret;
+-}
+-
+-// Validate checks that the contents is a valid digest
+-static bool validate_digest(const char *digest)
+-{
+- bool ret = true;
+- const char *sha256_encode_patten = "^[a-f0-9]{64}$";
+- char *value = util_strdup_s(digest);
+- char *index = strchr(value, ':');
+- char *alg = NULL;
+- char *encode = NULL;
+-
+- // contains ':' and is not the last character
+- if (index == NULL || index - value + 1 == strlen(value)) {
+- INFO("Invalid checksum digest format");
+- ret = false;
+- goto out;
+- }
+-
+- *index++ = '\0';
+-
+- alg = value;
+- encode = index;
+- // Currently only support SHA256 algorithm
+- if (strcmp(alg, "sha256") != 0) {
+- DEBUG("Unsupported digest algorithm: %s", alg);
+- ret = false;
+- goto out;
+- }
+-
+- ret = util_reg_match(sha256_encode_patten, encode) == 0;
+-
+-out:
+- free(value);
+- return ret;
+-}
+-
+-// Parsing a reference string as a possible identifier, full digest, or familiar name.
+-static char *parse_digest_reference(const char *ref)
+-{
+- char *indentfier_patten = "^[a-f0-9]{64}$";
+-
+- if (util_reg_match(indentfier_patten, ref) == 0) {
+- return util_string_append(ref, "sha256:");
+- }
+-
+- if (validate_digest(ref)) {
+- return util_strdup_s(ref);
+- }
+-
+- return oci_normalize_image_name(ref);
+-}
+-
+ static int pack_repo_digest(char ***old_repo_digests, const char **image_tags, const char *digest, char ***repo_digests)
+ {
+ int ret = 0;
+--
+2.42.0
+