提交 c138b0a2 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!658 more restricted created time check

Merge pull request !658 from wangfengtu/valid_time
......@@ -397,16 +397,15 @@ out:
static int check_time_valid(oci_image_spec *conf)
{
int64_t nanos = 0;
int i = 0;
if (to_unix_nanos_from_str(conf->created, &nanos) != 0) {
if (!oci_valid_time(conf->created)) {
ERROR("Invalid created time %s", conf->created);
return -1;
}
for (i = 0; i < conf->history_len; i++) {
if (to_unix_nanos_from_str(conf->history[i]->created, &nanos) != 0) {
if (!oci_valid_time(conf->history[i]->created)) {
ERROR("Invalid history created time %s", conf->history[i]->created);
return -1;
}
......
......@@ -802,6 +802,44 @@ out:
return ret;
}
static int check_time_valid(pull_descriptor *desc)
{
int ret = 0;
parser_error err = NULL;
size_t i = 0;
docker_image_config_v2 *conf = NULL;
// oci/docker's configs are compatable
conf = docker_image_config_v2_parse_file(desc->config.file, NULL, &err);
if (conf == NULL) {
ERROR("parse config failed: %s", err);
ret = -1;
goto out;
}
if (!oci_valid_time(conf->created)) {
ERROR("Invalid created time %s", conf->created);
ret = -1;
goto out;
}
for (i = 0; i < conf->history_len; i++) {
if (!oci_valid_time(conf->history[i]->created)) {
ERROR("Invalid history created time %s", conf->history[i]->created);
ret = -1;
goto out;
}
}
out:
free_docker_image_config_v2(conf);
conf = NULL;
free(err);
err = NULL;
return ret;
}
static int register_image(pull_descriptor *desc)
{
int ret = 0;
......@@ -814,6 +852,10 @@ static int register_image(pull_descriptor *desc)
return -1;
}
if (check_time_valid(desc) != 0) {
return -1;
}
ret = register_layers(desc);
if (ret != 0) {
ERROR("register layers for image %s failed", desc->dest_image_name);
......
......@@ -37,6 +37,9 @@
#include "utils_string.h"
#include "utils_verify.h"
// nanos of 2038-01-19T03:14:07, the max valid linux time
#define MAX_NANOS 2147483647000000000
char *get_last_part(char **parts)
{
char *last_part = NULL;
......@@ -518,3 +521,25 @@ out:
return timestamp;
}
bool oci_valid_time(char *time)
{
int64_t nanos = 0;
if (time == NULL) {
ERROR("Invalid NULL time");
return false;
}
if (to_unix_nanos_from_str(time, &nanos) != 0) {
ERROR("Failed to translate created time %s to nanos", time);
return false;
}
// valid created time range from utc time 1970-01-01T00:00:00 to 2038-01-19T03:14:07
if (nanos < 0 || nanos > MAX_NANOS) {
ERROR("Invalid time %s out of range 1970-01-01T00:00:00 to 2038-01-19T03:14:07", time);
return false;
}
return true;
}
......@@ -54,6 +54,7 @@ void free_items_not_inherit(docker_image_config_v2 *config);
int add_rootfs_and_history(const layer_blob *layers, size_t layers_len, const registry_manifest_schema1 *manifest,
docker_image_config_v2 *config);
types_timestamp_t created_to_timestamp(char *created);
bool oci_valid_time(char *time);
#ifdef __cplusplus
}
......
......@@ -435,9 +435,10 @@ bool fix_date(struct tm *tm)
return false;
}
// Max year 2100 is enough, do not be 9999, it can overflow when translate it to nanos
bool ret = (is_out_of_range(tm->tm_hour, 0, 23)) || (is_out_of_range(tm->tm_min, 0, 59)) ||
(is_out_of_range(tm->tm_sec, 0, 59)) || (is_out_of_range(tm->tm_mon, 1, 12)) ||
(is_out_of_range(tm->tm_year, 1900, 9999));
(is_out_of_range(tm->tm_year, 1900, 2100));
if (ret) {
ERROR("Normal section out of range");
......
......@@ -35,6 +35,7 @@ add_executable(${EXE}
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/auths.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/aes.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/storage_mock.cc
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/oci_image_mock.cc
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/http_mock.cc
registry_ut.cpp)
......
......@@ -42,6 +42,7 @@
#include "buffer.h"
#include "aes.h"
#include "auths.h"
#include "oci_image_mock.h"
using ::testing::Args;
using ::testing::ByRef;
......@@ -78,6 +79,7 @@ protected:
{
MockHttp_SetMock(&m_http_mock);
MockStorage_SetMock(&m_storage_mock);
MockOciImage_SetMock(&m_oci_image_mock);
}
void TearDown() override
......@@ -88,6 +90,7 @@ protected:
NiceMock<MockHttp> m_http_mock;
NiceMock<MockStorage> m_storage_mock;
NiceMock<MockOciImage> m_oci_image_mock;
};
int invokeHttpRequestV1(const char *url, struct http_get_options *options, long *response_code, int recursive_len)
......@@ -467,6 +470,11 @@ void invokeFreeLayer(struct layer *ptr)
free(ptr);
}
bool invokeOciValidTime(char *time)
{
return true;
}
static int init_log()
{
struct isula_libutils_log_config lconf = { 0 };
......@@ -483,7 +491,7 @@ static int init_log()
return 0;
}
void mockStorageAll(MockStorage *mock)
void mockCommonAll(MockStorage *mock, MockOciImage *oci_image_mock)
{
EXPECT_CALL(*mock, StorageImgCreate(::testing::_,::testing::_,::testing::_,::testing::_))
.WillRepeatedly(Invoke(invokeStorageImgCreate));
......@@ -513,6 +521,8 @@ void mockStorageAll(MockStorage *mock)
.WillRepeatedly(Invoke(invokeFreeLayerList));
EXPECT_CALL(*mock, FreeLayer(::testing::_))
.WillRepeatedly(Invoke(invokeFreeLayer));
EXPECT_CALL(*oci_image_mock, OciValidTime(::testing::_))
.WillRepeatedly(Invoke(invokeOciValidTime));
return;
}
......@@ -570,7 +580,7 @@ TEST_F(RegistryUnitTest, test_pull_v1_image)
EXPECT_CALL(m_http_mock, HttpRequest(::testing::_,::testing::_,::testing::_,::testing::_))
.WillRepeatedly(Invoke(invokeHttpRequestV1));
mockStorageAll(&m_storage_mock);
mockCommonAll(&m_storage_mock, &m_oci_image_mock);
ASSERT_EQ(registry_pull(&options), 0);
ASSERT_EQ(registry_pull(&options), 0);
......@@ -630,7 +640,7 @@ TEST_F(RegistryUnitTest, test_pull_v2_image)
EXPECT_CALL(m_http_mock, HttpRequest(::testing::_,::testing::_,::testing::_,::testing::_))
.WillRepeatedly(Invoke(invokeHttpRequestV2));
mockStorageAll(&m_storage_mock);
mockCommonAll(&m_storage_mock, &m_oci_image_mock);
// test retry success
ASSERT_EQ(registry_pull(&options), 0);
......@@ -664,7 +674,7 @@ TEST_F(RegistryUnitTest, test_pull_oci_image)
options->insecure_registry = false;
EXPECT_CALL(m_http_mock, HttpRequest(::testing::_,::testing::_,::testing::_,::testing::_))
.WillRepeatedly(Invoke(invokeHttpRequestOCI));
mockStorageAll(&m_storage_mock);
mockCommonAll(&m_storage_mock, &m_oci_image_mock);
ASSERT_EQ(registry_pull(options), 0);
free_registry_pull_options(options);
......@@ -682,7 +692,7 @@ TEST_F(RegistryUnitTest, test_pull_already_exist)
EXPECT_CALL(m_http_mock, HttpRequest(::testing::_,::testing::_,::testing::_,::testing::_))
.WillRepeatedly(Invoke(invokeHttpRequestV2));
mockStorageAll(&m_storage_mock);
mockCommonAll(&m_storage_mock, &m_oci_image_mock);
EXPECT_CALL(m_storage_mock, StorageLayerGet(::testing::_))
.WillRepeatedly(Invoke(invokeStorageLayerGet1));
ASSERT_EQ(registry_pull(&options), 0);
......
/******************************************************************************
* Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
* iSulad licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v2 for more details.
* Author: wangfengtu
* Create: 2020-08-20
* Description: provide oci image mock
******************************************************************************/
#include "oci_image_mock.h"
namespace {
MockOciImage *g_oci_image_mock = NULL;
}
void MockOciImage_SetMock(MockOciImage* mock)
{
g_oci_image_mock = mock;
}
bool oci_valid_time(char *time)
{
if (g_oci_image_mock != nullptr) {
return g_oci_image_mock->OciValidTime(time);
}
return false;
}
/******************************************************************************
* Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
* iSulad licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v2 for more details.
* Author: wangfengtu
* Create: 2020-08-20
* Description: provide oci image mock
******************************************************************************/
#ifndef _ISULAD_TEST_MOCKS_OCI_IMAGE_MOCK_H
#define _ISULAD_TEST_MOCKS_OCI_IMAGE_MOCK_H
#include <gmock/gmock.h>
#include "oci_image.h"
class MockOciImage {
public:
virtual ~MockOciImage() = default;
MOCK_METHOD1(OciValidTime, bool(char *time));
};
void MockOciImage_SetMock(MockOciImage *mock);
#endif // _ISULAD_TEST_MOCKS_OCI_IMAGE_MOCK_H
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册