diff --git a/0001-support-check-symbols-and-compile-code-in-cmake.patch b/0001-support-check-symbols-and-compile-code-in-cmake.patch new file mode 100644 index 0000000..877a45c --- /dev/null +++ b/0001-support-check-symbols-and-compile-code-in-cmake.patch @@ -0,0 +1,37 @@ +From 6646d4020ba6e1ea2bf4a129cd7188368e18d3bc Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Sat, 26 Aug 2023 10:54:02 +0800 +Subject: [PATCH 1/8] support check symbols and compile code in cmake + +Signed-off-by: haozi007 +--- + cmake/checker.cmake | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/cmake/checker.cmake b/cmake/checker.cmake +index 13c1cdb..27a83d1 100644 +--- a/cmake/checker.cmake ++++ b/cmake/checker.cmake +@@ -20,6 +20,9 @@ + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + # + ++include(CheckFunctionExists) ++include(CheckCSourceCompiles) ++ + # check depends library and headers + find_package(PkgConfig REQUIRED) + +@@ -91,3 +94,9 @@ if (ENABLE_GCOV) + _CHECK(CMD_GENHTML "CMD_GENHTML-NOTFOUND" "genhtml") + endif() + ++check_function_exists(strerror_r HAVE_STRERROR_R) ++ ++check_c_source_compiles( ++ "#define _GNU_SOURCE\n#include \nint main() { char err_str[128]; char *ptr = strerror_r(-2, err_str, 128); return ptr != (void *)0L; }" ++ STRERROR_R_CHAR_P ++) +-- +2.34.1 + diff --git a/0002-remove-unnecessary-strerror.patch b/0002-remove-unnecessary-strerror.patch new file mode 100644 index 0000000..77b7e88 --- /dev/null +++ b/0002-remove-unnecessary-strerror.patch @@ -0,0 +1,97 @@ +From 24579633671fca855dd1c66a4d7614ccf2e7e388 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Tue, 5 Sep 2023 19:35:37 +0800 +Subject: [PATCH 2/8] remove unnecessary strerror + +Signed-off-by: haozi007 +--- + src/runtime/lcrcontainer_execute.c | 3 +-- + src/runtime/lcrcontainer_extend.c | 16 ++++++++-------- + 2 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/runtime/lcrcontainer_execute.c b/src/runtime/lcrcontainer_execute.c +index 864c097..f2bb944 100644 +--- a/src/runtime/lcrcontainer_execute.c ++++ b/src/runtime/lcrcontainer_execute.c +@@ -71,8 +71,7 @@ + do \ + { \ + SYSERROR("Error updating cgroup %s to %s", (item), (value)); \ +- lcr_set_error_message(LCR_ERR_RUNTIME, "Error updating cgroup %s to %s: %s", (item), (value), \ +- strerror(errno)); \ ++ lcr_set_error_message(LCR_ERR_RUNTIME, "Error updating cgroup %s to %s.", (item), (value)); \ + } while (0) + + static inline void add_array_elem(char **array, size_t total, size_t *pos, const char *elem) +diff --git a/src/runtime/lcrcontainer_extend.c b/src/runtime/lcrcontainer_extend.c +index 2f3ae9f..8b5a85c 100644 +--- a/src/runtime/lcrcontainer_extend.c ++++ b/src/runtime/lcrcontainer_extend.c +@@ -153,7 +153,7 @@ static int make_annotations(oci_runtime_spec *container, const struct lxc_contai + goto out; + } + if (lcr_util_ensure_path(&realpath, anno->values[fpos])) { +- ERROR("Invalid log path: %s, error: %s.", anno->values[fpos], strerror(errno)); ++ SYSERROR("Invalid log path: %s.", anno->values[fpos]); + goto out; + } + ret = 0; +@@ -378,7 +378,7 @@ static int lcr_spec_write_seccomp_line(FILE *fp, const char *seccomp) + + line[nret] = '\n'; + if (fwrite(line, 1, len ,fp) != len) { +- ERROR("Write file failed: %s", strerror(errno)); ++ SYSERROR("Write file failed"); + goto cleanup; + } + +@@ -743,8 +743,8 @@ static FILE *lcr_open_config_file(const char *bundle) + + fd = lcr_util_open(real_config, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE); + if (fd == -1) { +- ERROR("Create file %s failed, %s", real_config, strerror(errno)); +- lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed, %s", real_config, strerror(errno)); ++ SYSERROR("Create file %s failed", real_config); ++ lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", real_config); + goto out; + } + +@@ -856,7 +856,7 @@ static int lcr_spec_write_config(FILE *fp, const struct lcr_list *lcr_conf) + line_encode[len] = '\n'; + + if (fwrite(line_encode, 1, len + 1, fp) != len + 1) { +- ERROR("Write file failed: %s", strerror(errno)); ++ SYSERROR("Write file failed"); + goto cleanup; + } + +@@ -908,7 +908,7 @@ char *lcr_get_bundle(const char *lcrpath, const char *name) + ERROR("Bundle %s does not exist", bundle); + break; + default: +- ERROR("Access %s failed: %s\n", bundle, strerror(errno)); ++ SYSERROR("Access %s failed", bundle); + } + goto cleanup; + } +@@ -995,7 +995,7 @@ static int lcr_write_file(const char *path, const char *data, size_t len) + } + + if (write(fd, data, len) == -1) { +- ERROR("write data to %s failed: %s", real_path, strerror(errno)); ++ SYSERROR("write data to %s failed", real_path); + goto out_free; + } + +@@ -1023,7 +1023,7 @@ static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *h + } + + if (lcr_write_file(path, json_hooks, strlen(json_hooks)) == -1) { +- ERROR("write json hooks failed: %s", strerror(errno)); ++ SYSERROR("write json hooks failed"); + goto out_free; + } + +-- +2.34.1 + diff --git a/0003-improve-code-of-function-in-log.patch b/0003-improve-code-of-function-in-log.patch new file mode 100644 index 0000000..66f5496 --- /dev/null +++ b/0003-improve-code-of-function-in-log.patch @@ -0,0 +1,82 @@ +From 19810333a97614619a1e2c945c253c964ef02d3b Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Wed, 6 Sep 2023 14:22:21 +0800 +Subject: [PATCH 3/8] improve code of function in log + +Signed-off-by: haozi007 +--- + src/runtime/lcrcontainer_execute.c | 4 ++-- + src/third_party/log.c | 6 +++--- + src/third_party/log.h | 4 ++-- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/runtime/lcrcontainer_execute.c b/src/runtime/lcrcontainer_execute.c +index f2bb944..e91ff27 100644 +--- a/src/runtime/lcrcontainer_execute.c ++++ b/src/runtime/lcrcontainer_execute.c +@@ -883,7 +883,7 @@ static void execute_lxc_attach(const char *name, const char *path, const struct + + execvp("lxc-attach", params); + +- COMMAND_ERROR("Failed to exec lxc-attach: %s", strerror(errno)); ++ CMD_SYSERROR("Failed to exec lxc-attach"); + free(params); + exit(EXIT_FAILURE); + } +@@ -1027,6 +1027,6 @@ void execute_lxc_start(const char *name, const char *path, const struct lcr_star + + execvp("lxc-start", params); + +- COMMAND_ERROR("Failed to exec lxc-start: %s.", strerror(errno)); ++ CMD_SYSERROR("Failed to exec lxc-start."); + exit(EXIT_FAILURE); + } +diff --git a/src/third_party/log.c b/src/third_party/log.c +index 5ba638b..5097eb8 100644 +--- a/src/third_party/log.c ++++ b/src/third_party/log.c +@@ -309,18 +309,18 @@ static int open_fifo(const char *fifo_path) + + nret = mknod(fifo_path, S_IFIFO | S_IRUSR | S_IWUSR, (dev_t)0); + if (nret && errno != EEXIST) { +- COMMAND_ERROR("Mknod failed: %s", strerror(errno)); ++ CMD_SYSERROR("Mknod failed"); + return nret; + } + + fifo_fd = lcr_util_open(fifo_path, O_RDWR | O_NONBLOCK, 0); + if (fifo_fd == -1) { +- COMMAND_ERROR("Open fifo %s failed: %s", fifo_path, strerror(errno)); ++ CMD_SYSERROR("Open fifo %s failed", fifo_path); + return -1; + } + + if (fcntl(fifo_fd, F_SETPIPE_SZ, LOG_FIFO_SIZE) == -1) { +- COMMAND_ERROR("Set fifo buffer size failed: %s", strerror(errno)); ++ CMD_SYSERROR("Set fifo buffer size failed"); + close(fifo_fd); + return -1; + } +diff --git a/src/third_party/log.h b/src/third_party/log.h +index 3462b17..d0e5fa8 100644 +--- a/src/third_party/log.h ++++ b/src/third_party/log.h +@@ -417,13 +417,13 @@ lxc_log_priority_define(&g_lxc_log_category_lxc, FATAL); + #define CMD_SYSERROR(format, ...) \ + do { \ + lxc_log_strerror_r; \ +- fprintf(stderr, "%s - " format, ptr, ##__VA_ARGS__); \ ++ fprintf(stderr, "%s - " format "\n", ptr, ##__VA_ARGS__); \ + } while (0) + + #define CMD_SYSINFO(format, ...) \ + do { \ + lxc_log_strerror_r; \ +- printf("%s - " format, ptr, ##__VA_ARGS__); \ ++ printf("%s - " format "\n", ptr, ##__VA_ARGS__); \ + } while (0) + + #define COMMAND_ERROR(fmt, args...) \ +-- +2.34.1 + diff --git a/0004-support-visibility-of-compiler.patch b/0004-support-visibility-of-compiler.patch new file mode 100644 index 0000000..b1af4ee --- /dev/null +++ b/0004-support-visibility-of-compiler.patch @@ -0,0 +1,338 @@ +From ed36936f30525704f71e3b7444c1d25ffe50ab2f Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Tue, 12 Sep 2023 10:27:05 +0800 +Subject: [PATCH 4/8] support visibility of compiler + +use visibility for liblcr + +Signed-off-by: haozi007 +--- + CMakeLists.txt | 4 +-- + src/CMakeLists.txt | 1 + + src/runtime/lcrcontainer.h | 68 ++++++++++++++++++++------------------ + src/utils/utils_compile.h | 50 ++++++++++++++++++++++++++++ + 4 files changed, 88 insertions(+), 35 deletions(-) + create mode 100644 src/utils/utils_compile.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a51ac7d..e00dc96 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -117,8 +117,8 @@ install(FILES ${CMAKE_BINARY_DIR}/conf/lcr.pc + DESTINATION ${LIB_INSTALL_DIR_DEFAULT}/pkgconfig PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE WORLD_READ WORLD_EXECUTE) + install(FILES ${CMAKE_BINARY_DIR}/conf/libisula.pc + DESTINATION ${LIB_INSTALL_DIR_DEFAULT}/pkgconfig PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE WORLD_READ WORLD_EXECUTE) +-install(FILES src/runtime/lcrcontainer.h +- DESTINATION include/lcr) ++install(FILES src/runtime/lcrcontainer.h DESTINATION include/lcr) ++install(FILES src/utils/utils_compile.h DESTINATION include/lcr) + + install(FILES src/third_party/log.h DESTINATION include/isula_libutils) + install(FILES src/third_party/go_crc64.h DESTINATION include/isula_libutils) +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 2bf468f..c423dd7 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -124,6 +124,7 @@ target_include_directories(liblcr + # set liblcr compile flags + set_target_properties(liblcr PROPERTIES PREFIX "") + target_link_libraries(liblcr ${check_libs} isula_libutils) ++target_compile_options(liblcr PRIVATE -fvisibility=hidden) + + if (CMAKE_TOOLCHAIN_FILE) + target_link_directories(liblcr PUBLIC ${CMAKE_LIBRARY_PATH}) +diff --git a/src/runtime/lcrcontainer.h b/src/runtime/lcrcontainer.h +index edfc869..6add8c4 100644 +--- a/src/runtime/lcrcontainer.h ++++ b/src/runtime/lcrcontainer.h +@@ -32,13 +32,15 @@ + #include + #include + ++#include "utils_compile.h" ++ + #ifdef __cplusplus + extern "C" { + #endif + + /* define console log config */ + +-struct lcr_console_config { ++__EXPORT__ struct lcr_console_config { + char *log_path; + unsigned int log_rotate; + char *log_file_size; +@@ -47,7 +49,7 @@ struct lcr_console_config { + /* + * Store lcr container info + */ +-struct lcr_container_info { ++__EXPORT__ struct lcr_container_info { + /* Name of container. */ + char *name; + /* State of container. */ +@@ -62,7 +64,7 @@ struct lcr_container_info { + bool running; + }; + +-struct blkio_stats { ++__EXPORT__ struct blkio_stats { + uint64_t read; + uint64_t write; + uint64_t total; +@@ -71,7 +73,7 @@ struct blkio_stats { + /* + * Store lcr container state + */ +-struct lcr_container_state { ++__EXPORT__ struct lcr_container_state { + /* Name of container */ + char *name; + /* State of container */ +@@ -108,14 +110,14 @@ typedef enum { + lcr_msg_exit_code, + } lcr_msg_type_t; + +-struct lcr_msg { ++__EXPORT__ struct lcr_msg { + lcr_msg_type_t type; + char name[NAME_MAX + 1]; + int value; + int pid; + }; + +-struct lcr_cgroup_resources { ++__EXPORT__ struct lcr_cgroup_resources { + uint64_t blkio_weight; + uint64_t cpu_shares; + uint64_t cpu_period; +@@ -134,23 +136,23 @@ struct lcr_cgroup_resources { + * Get one container info for a given lcrpath. + * return struct of container info, or NULL on error. + */ +-struct lcr_container_info *lcr_container_info_get(const char *name, const char *lcrpath); ++__EXPORT__ struct lcr_container_info *lcr_container_info_get(const char *name, const char *lcrpath); + + /* + * Free lcr_container_info returned lcr_container_info_get + */ +-void lcr_container_info_free(struct lcr_container_info *info); ++__EXPORT__ void lcr_container_info_free(struct lcr_container_info *info); + + /* + * Get a complete list of all containers for a given lcrpath. + * return Number of containers, or -1 on error. + */ +-int lcr_list_all_containers(const char *lcrpath, struct lcr_container_info **info_arr); ++__EXPORT__ int lcr_list_all_containers(const char *lcrpath, struct lcr_container_info **info_arr); + + /* + * Free lcr_container_info array returned by lcr_list_{active,all}_containers + */ +-void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size); ++__EXPORT__ void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size); + + /* + * Create a container +@@ -158,7 +160,7 @@ void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size) + * param lcrpath : container path + * param oci_json_data : json string of oci config data + */ +-bool lcr_create_from_ocidata(const char *name, const char *lcrpath, const void *oci_json_data); ++__EXPORT__ bool lcr_create_from_ocidata(const char *name, const char *lcrpath, const void *oci_json_data); + + /* + * Create a container +@@ -166,7 +168,7 @@ bool lcr_create_from_ocidata(const char *name, const char *lcrpath, const void * + * param lcrpath : container path + * param oci_config : pointer of struct oci config + */ +-bool lcr_create(const char *name, const char *lcrpath, void *oci_config); ++__EXPORT__ bool lcr_create(const char *name, const char *lcrpath, void *oci_config); + + /* + * Start a container +@@ -188,7 +190,7 @@ bool lcr_create(const char *name, const char *lcrpath, void *oci_config); + * gid : user in which group + * additional_gids : Add additional groups to join + */ +-struct lcr_start_request { ++__EXPORT__ struct lcr_start_request { + const char *name; + const char *lcrpath; + +@@ -204,7 +206,7 @@ struct lcr_start_request { + const char *exit_fifo; + bool image_type_oci; + }; +-bool lcr_start(const struct lcr_start_request *request); ++__EXPORT__ bool lcr_start(const struct lcr_start_request *request); + + /* + * Stop a container +@@ -212,7 +214,7 @@ bool lcr_start(const struct lcr_start_request *request); + * param lcrpath : container path, set to NULL if you want use default lcrpath. + * param signal : signal to send to the container. + */ +-bool lcr_kill(const char *name, const char *lcrpath, uint32_t signal); ++__EXPORT__ bool lcr_kill(const char *name, const char *lcrpath, uint32_t signal); + + /* + * Delete a container +@@ -220,9 +222,9 @@ bool lcr_kill(const char *name, const char *lcrpath, uint32_t signal); + * param lcrpath : container path, set to NULL if you want use default lcrpath. + * param force : force to delete container + */ +-bool lcr_delete(const char *name, const char *lcrpath); ++__EXPORT__ bool lcr_delete(const char *name, const char *lcrpath); + +-bool lcr_clean(const char *name, const char *lcrpath, const char *logpath, const char *loglevel, pid_t pid); ++__EXPORT__ bool lcr_clean(const char *name, const char *lcrpath, const char *logpath, const char *loglevel, pid_t pid); + + /* + * Get state of the container +@@ -230,26 +232,26 @@ bool lcr_clean(const char *name, const char *lcrpath, const char *logpath, const + * param lcrpath : container path, set to NULL if you want use default lcrpath. + * param lcs : returned contaiener state + */ +-bool lcr_state(const char *name, const char *lcrpath, struct lcr_container_state *lcs); ++__EXPORT__ bool lcr_state(const char *name, const char *lcrpath, struct lcr_container_state *lcs); + + /* + * Pause a container + * param name : container name, required. + * param lcrpath : container path, set to NULL if you want use default lcrpath. + */ +-bool lcr_pause(const char *name, const char *lcrpath); ++__EXPORT__ bool lcr_pause(const char *name, const char *lcrpath); + + /* + * Resume a container + * param name : container name, required. + * param lcrpath : container path, set to NULL if you want use default lcrpath. + */ +-bool lcr_resume(const char *name, const char *lcrpath); ++__EXPORT__ bool lcr_resume(const char *name, const char *lcrpath); + + /* + * Free lcr_container_state returned by lcr_state + */ +-void lcr_container_state_free(struct lcr_container_state *lcs); ++__EXPORT__ void lcr_container_state_free(struct lcr_container_state *lcs); + + /* + * console function +@@ -259,7 +261,7 @@ void lcr_container_state_free(struct lcr_container_state *lcs); + * param out_fifo : fifo names of output FIFO + * Returns false if the console FIFOs add failed, true if success + */ +-bool lcr_console(const char *name, const char *lcrpath, const char *in_fifo, const char *out_fifo, ++__EXPORT__ bool lcr_console(const char *name, const char *lcrpath, const char *in_fifo, const char *out_fifo, + const char *err_fifo); + + /* +@@ -268,14 +270,14 @@ bool lcr_console(const char *name, const char *lcrpath, const char *in_fifo, con + * param lcrpath : container path, set to NULL if you want use default lcrpath. + * param config : use to store container console configs, cannot be NULL + */ +-bool lcr_get_console_config(const char *name, const char *lcrpath, struct lcr_console_config *config); ++__EXPORT__ bool lcr_get_console_config(const char *name, const char *lcrpath, struct lcr_console_config *config); + +-void lcr_free_console_config(struct lcr_console_config *config); ++__EXPORT__ void lcr_free_console_config(struct lcr_console_config *config); + +-int lcr_log_init(const char *name, const char *file, const char *priority, ++__EXPORT__ int lcr_log_init(const char *name, const char *file, const char *priority, + const char *prefix, int quiet, const char *lcrpath); + +-struct lcr_exec_request { ++__EXPORT__ struct lcr_exec_request { + const char *name; + const char *lcrpath; + +@@ -303,18 +305,18 @@ struct lcr_exec_request { + /* + * Execute process inside a container + */ +-bool lcr_exec(const struct lcr_exec_request *request, int *exit_code); ++__EXPORT__ bool lcr_exec(const struct lcr_exec_request *request, int *exit_code); + +-bool lcr_update(const char *name, const char *lcrpath, const struct lcr_cgroup_resources *cr); ++__EXPORT__ bool lcr_update(const char *name, const char *lcrpath, const struct lcr_cgroup_resources *cr); + +-const char *lcr_get_errmsg(); ++__EXPORT__ const char *lcr_get_errmsg(); + +-void lcr_free_errmsg(); ++__EXPORT__ void lcr_free_errmsg(); + +-bool lcr_get_container_pids(const char *name, const char *lcrpath, pid_t **pids, size_t *pids_len); ++__EXPORT__ bool lcr_get_container_pids(const char *name, const char *lcrpath, pid_t **pids, size_t *pids_len); + +-bool lcr_resize(const char *name, const char *lcrpath, unsigned int height, unsigned int width); +-bool lcr_exec_resize(const char *name, const char *lcrpath, const char *suffix, unsigned int height, ++__EXPORT__ bool lcr_resize(const char *name, const char *lcrpath, unsigned int height, unsigned int width); ++__EXPORT__ bool lcr_exec_resize(const char *name, const char *lcrpath, const char *suffix, unsigned int height, + unsigned int width); + #ifdef __cplusplus + } +diff --git a/src/utils/utils_compile.h b/src/utils/utils_compile.h +new file mode 100644 +index 0000000..3bdb24e +--- /dev/null ++++ b/src/utils/utils_compile.h +@@ -0,0 +1,50 @@ ++/****************************************************************************** ++ * isula: compile utils ++ * ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. ++ * ++ * Authors: ++ * Haozi007 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ********************************************************************************/ ++#ifndef _ISULA_UTILS_UTILS_COMPILE_H ++#define _ISULA_UTILS_UTILS_COMPILE_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#if defined(__GNUC__) && (__GNUC__ >= 4) ++#ifndef __HIDDEN__ ++#define __HIDDEN__ __attribute__((visibility("hidden"))) ++#endif ++ ++#ifndef __EXPORT__ ++#define __EXPORT__ __attribute__((visibility("default"))) ++#endif ++ ++#else ++#define __HIDDEN__ ++#ifndef __EXPORT__ ++#endif ++ ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _ISULA_UTILS_UTILS_COMPILE_H */ +\ No newline at end of file +-- +2.34.1 + diff --git a/0005-refactor-util-buffer-and-add-ut.patch b/0005-refactor-util-buffer-and-add-ut.patch new file mode 100644 index 0000000..5cb7b55 --- /dev/null +++ b/0005-refactor-util-buffer-and-add-ut.patch @@ -0,0 +1,1098 @@ +From 9eff61689ae66c2531750d1bf1c8e551f6b576a9 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Wed, 13 Sep 2023 11:05:19 +0800 +Subject: [PATCH 5/8] refactor util buffer and add ut + +Signed-off-by: haozi007 +--- + CMakeLists.txt | 3 +- + src/CMakeLists.txt | 25 ++- + src/buffer.h | 39 ----- + src/constants.h | 8 + + src/runtime/conf.c | 32 ++-- + src/runtime/conf.h | 8 + + src/runtime/lcr_list.h | 7 + + src/{buffer.c => utils/utils_buffer.c} | 189 ++++++++++++---------- + src/utils/utils_buffer.h | 93 +++++++++++ + tests/CMakeLists.txt | 35 +++- + tests/auto_cleanup_ut.cpp | 19 +++ + tests/utils_buffer_ut.cpp | 213 +++++++++++++++++++++++++ + 12 files changed, 516 insertions(+), 155 deletions(-) + delete mode 100644 src/buffer.h + rename src/{buffer.c => utils/utils_buffer.c} (60%) + create mode 100644 src/utils/utils_buffer.h + create mode 100644 tests/utils_buffer_ut.cpp + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e00dc96..2bbb829 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -128,7 +128,8 @@ install(FILES src/json/parse_common.h DESTINATION include/isula_libutils) + install(DIRECTORY ${CMAKE_BINARY_DIR}/json/ DESTINATION include/isula_libutils + FILES_MATCHING PATTERN "*.h") + install(FILES src/auto_cleanup.h DESTINATION include/isula_libutils) +-# donot export utils now ++# export utils here ++install(FILES src/utils/utils_buffer.h DESTINATION include/isula_libutils) + + # uninstall + if(NOT TARGET uninstall) +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index c423dd7..cb076e8 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -92,16 +92,29 @@ target_include_directories(isula_libutils + + target_link_libraries(isula_libutils ${check_isula_utils_libs}) + +-add_library(isula_libutils_s ++add_library(isulad_shim_libutils + STATIC +- ${isula_libutils_srcs} ++ ${topsrcs} ++ ${THIRD_PARTY_SRCS} ++ ${commonjsonsrcs} ++ ${topjsonsrcs} ++ ${UTILS_SRCS} ++ ${CMAKE_BINARY_DIR}/json/logger_json_file.c ++ ${CMAKE_BINARY_DIR}/json/shim_client_process_state.c ++ ${CMAKE_BINARY_DIR}/json/shim_client_runtime_stats.c ++ ${CMAKE_BINARY_DIR}/json/shim_client_cgroup_resources.c ++ ${CMAKE_BINARY_DIR}/json/json_common.c ++ ${CMAKE_BINARY_DIR}/json/defs.c ++ ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c ++ ${CMAKE_BINARY_DIR}/json/oci_runtime_pspec.c ++ ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c ++ ${CMAKE_BINARY_DIR}/json/oci_runtime_state.c + ) + +-target_include_directories(isula_libutils_s ++target_include_directories(isulad_shim_libutils + PUBLIC ${isula_libutils_incs} + ) +-target_link_libraries(isula_libutils_s ${check_isula_utils_libs}) +-set_target_properties(isula_libutils_s PROPERTIES OUTPUT_NAME isula_libutils) ++target_link_libraries(isulad_shim_libutils ${LIBYAJL_LIBRARY}) + + if (ENABLE_LIBLCR) + # set liblcr library +@@ -149,5 +162,5 @@ endif() + + install(TARGETS isula_libutils + LIBRARY DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +-install(TARGETS isula_libutils_s ++install(TARGETS isulad_shim_libutils + ARCHIVE DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +diff --git a/src/buffer.h b/src/buffer.h +deleted file mode 100644 +index b7777ab..0000000 +--- a/src/buffer.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-/****************************************************************************** +- * lcr: utils library for iSula +- * +- * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +- * +- * Authors: +- * Haozi007 +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- ********************************************************************************/ +- +-#ifndef _ISULA_UTILS_BUFFER_H +-#define _ISULA_UTILS_BUFFER_H +- +-#include +- +-typedef struct Buffer { +- char *contents; +- size_t bytes_used; +- size_t total_size; +-} Buffer; +- +-Buffer *buffer_alloc(size_t initial_size); +-void buffer_free(Buffer *buf); +-int buffer_nappendf(Buffer *buf, size_t length, const char *format, ...); +-char *buffer_to_s(const Buffer *buf); +-#endif +diff --git a/src/constants.h b/src/constants.h +index 85a3196..b62026d 100644 +--- a/src/constants.h ++++ b/src/constants.h +@@ -24,6 +24,10 @@ + #ifndef _ISULA_UTILS_CONSTANTS_H + #define _ISULA_UTILS_CONSTANTS_H + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /* mode of file and directory */ + + #define DEFAULT_SECURE_FILE_MODE 0640 +@@ -53,4 +57,8 @@ + /* buffer constants defined here */ + #define ISULA_PAGE_BUFSIZE 4096 + ++#ifdef __cplusplus ++} ++#endif ++ + #endif +diff --git a/src/runtime/conf.c b/src/runtime/conf.c +index 4554599..d505507 100644 +--- a/src/runtime/conf.c ++++ b/src/runtime/conf.c +@@ -36,7 +36,7 @@ + #include "utils.h" + #include "log.h" + +-#include "buffer.h" ++#include "utils_buffer.h" + #include "lcr_list.h" + #include "constants.h" + +@@ -2665,7 +2665,7 @@ static bool is_action_allow(const char *value) + + #define DEFAULT_ACTION_OFFSET 12 + /* seccomp append head info */ +-static int seccomp_append_head_info(const char *action, Buffer *buffer) ++static int seccomp_append_head_info(const char *action, isula_buffer *buffer) + { + int ret = 0; + char *default_action = NULL; +@@ -2681,9 +2681,9 @@ static int seccomp_append_head_info(const char *action, Buffer *buffer) + } + + if (is_action_allow(default_action)) { +- ret = buffer_nappendf(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "blacklist %s\n", default_action); ++ ret = buffer->nappend(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "blacklist %s\n", default_action); + } else { +- ret = buffer_nappendf(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "whitelist %s\n", default_action); ++ ret = buffer->nappend(buffer, strlen(default_action) + DEFAULT_ACTION_OFFSET, "whitelist %s\n", default_action); + } + if (ret != 0) { + ERROR("Failed to append seccomp config head info\n"); +@@ -2773,7 +2773,7 @@ static char *seccomp_trans_arch(const char *arch) + } + + /* seccomp append arch */ +-static int seccomp_append_arch(char *arch, Buffer *buffer) ++static int seccomp_append_arch(char *arch, isula_buffer *buffer) + { + int ret = 0; + char *trans_arch = NULL; +@@ -2788,7 +2788,7 @@ static int seccomp_append_arch(char *arch, Buffer *buffer) + return -1; + } + +- if (buffer_nappendf(buffer, strlen(trans_arch) + 2, "%s\n", trans_arch)) { ++ if (buffer->nappend(buffer, strlen(trans_arch) + 2, "%s\n", trans_arch)) { + ERROR("Failed to append seccomp config head info\n"); + ret = -1; + } +@@ -2798,7 +2798,7 @@ static int seccomp_append_arch(char *arch, Buffer *buffer) + } + + /* seccomp append rule */ +-static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *buffer, char *action) ++static int seccomp_append_rule(const defs_syscall *syscall, size_t i, isula_buffer *buffer, char *action) + { + int ret = 0; + size_t j = 0; +@@ -2808,7 +2808,7 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *bu + ret = -1; + goto out; + } +- if (buffer_nappendf(buffer, strlen(syscall->names[i]) + strlen(action) + 2, "%s %s", syscall->names[i], action)) { ++ if (buffer->nappend(buffer, strlen(syscall->names[i]) + strlen(action) + 2, "%s %s", syscall->names[i], action)) { + ERROR("Failed to append syscall name and action\n"); + ret = -1; + goto out; +@@ -2820,7 +2820,7 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *bu + ret = -1; + goto out; + } +- if (buffer_nappendf(buffer, 20 * 3 + strlen(syscall->args[j]->op), " [%u,%llu,%s,%llu]", ++ if (buffer->nappend(buffer, 20 * 3 + strlen(syscall->args[j]->op), " [%u,%llu,%s,%llu]", + syscall->args[j]->index, syscall->args[j]->value, syscall->args[j]->op, + syscall->args[j]->value_two)) { + ERROR("Failed to append syscall rules\n"); +@@ -2829,7 +2829,7 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, Buffer *bu + } + } + +- if (buffer_nappendf(buffer, 2, "\n")) { ++ if (buffer->append(buffer, "\n")) { + ERROR("Failed to append newline\n"); + ret = -1; + goto out; +@@ -2839,7 +2839,7 @@ out: + } + + /* seccomp append rules */ +-static int seccomp_append_rules(const defs_syscall *syscall, Buffer *buffer) ++static int seccomp_append_rules(const defs_syscall *syscall, isula_buffer *buffer) + { + int ret = 0; + size_t i = 0; +@@ -2905,7 +2905,7 @@ out_free: + return NULL; + } + +-static int append_seccomp_with_archs(const oci_runtime_config_linux_seccomp *seccomp, Buffer *buffer) ++static int append_seccomp_with_archs(const oci_runtime_config_linux_seccomp *seccomp, isula_buffer *buffer) + { + int ret = 0; + size_t i = 0; +@@ -2963,14 +2963,14 @@ static int trans_oci_seccomp(const oci_runtime_config_linux_seccomp *seccomp, ch + size_t j = 0; + size_t init_size = 4 * SIZE_KB; + +- Buffer *buffer = buffer_alloc(init_size); ++ isula_buffer *buffer = isula_buffer_alloc(init_size); + if (buffer == NULL) { + ERROR("Failed to malloc output_buffer\n"); + return -1; + } + + /* config version */ +- if (buffer_nappendf(buffer, 3, "2\n")) { ++ if (buffer->append(buffer, "2\n")) { + ERROR("Failed to append seccomp config version\n"); + ret = -1; + goto out_free; +@@ -2997,14 +2997,14 @@ static int trans_oci_seccomp(const oci_runtime_config_linux_seccomp *seccomp, ch + } + } + } +- *seccomp_conf = buffer_to_s(buffer); ++ *seccomp_conf = buffer->to_str(buffer); + if (*seccomp_conf == NULL) { + ret = -1; + goto out_free; + } + + out_free: +- buffer_free(buffer); ++ isula_buffer_free(buffer); + return ret; + } + +diff --git a/src/runtime/conf.h b/src/runtime/conf.h +index 6dfef79..38c1a3e 100644 +--- a/src/runtime/conf.h ++++ b/src/runtime/conf.h +@@ -26,6 +26,10 @@ + + #include "oci_runtime_spec.h" + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #define INVALID_INT 0 + + /* +@@ -118,4 +122,8 @@ struct lcr_list *get_needed_lxc_conf(); + + bool is_system_container(const oci_runtime_spec *container); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /*__LCR_CONF_H*/ +diff --git a/src/runtime/lcr_list.h b/src/runtime/lcr_list.h +index bdf1f1b..86a13e0 100644 +--- a/src/runtime/lcr_list.h ++++ b/src/runtime/lcr_list.h +@@ -24,6 +24,9 @@ + #ifndef __LCR_LIST_H + #define __LCR_LIST_H + ++#ifdef __cplusplus ++extern "C" { ++#endif + + struct lcr_list { + void *elem; +@@ -144,4 +147,8 @@ static inline size_t lcr_list_len(struct lcr_list *list) + return i; + } + ++#ifdef __cplusplus ++} ++#endif ++ + #endif +diff --git a/src/buffer.c b/src/utils/utils_buffer.c +similarity index 60% +rename from src/buffer.c +rename to src/utils/utils_buffer.c +index ca103ff..da34991 100644 +--- a/src/buffer.c ++++ b/src/utils/utils_buffer.c +@@ -20,68 +20,28 @@ + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ********************************************************************************/ +- + #define _GNU_SOURCE + +-#include +-#include ++#include "utils_buffer.h" + +-#include "buffer.h" ++#include "utils_memory.h" + #include "log.h" +-#include "utils.h" + #include "auto_cleanup.h" + +-/* buffer allocate */ +-Buffer *buffer_alloc(size_t initial_size) +-{ +- Buffer *buf = NULL; +- char *tmp = NULL; +- +- if (initial_size == 0) { +- return NULL; +- } +- +- buf = lcr_util_common_calloc_s(sizeof(Buffer)); +- if (buf == NULL) { +- return NULL; +- } +- +- tmp = calloc(1, initial_size); +- if (tmp == NULL) { +- free(buf); +- return NULL; +- } +- +- buf->contents = tmp; +- buf->bytes_used = 0; +- buf->total_size = initial_size; +- +- return buf; +-} +- +-/* buffer strlen */ +-static size_t buffer_strlen(const Buffer *buf) +-{ +- return buf == NULL ? 0 : buf->bytes_used; +-} +- +-/* buffer free */ +-void buffer_free(Buffer *buf) ++void isula_buffer_clear(isula_buffer *buf) + { + if (buf == NULL) { + return; + } +- free(buf->contents); +- buf->contents = NULL; +- free(buf); ++ (void)memset(buf->contents, 0, buf->total_size); ++ buf->bytes_used = 0; + } + +-/* buffer has space */ +-static bool buffer_has_space(const Buffer *buf, size_t desired_length) ++static bool buffer_has_space(const isula_buffer *buf, size_t desired_length) + { +- size_t bytes_remaining = 0; ++ size_t bytes_remaining; + +- if (buf == NULL) { ++ if (buf->total_size < buf->bytes_used) { + return false; + } + bytes_remaining = buf->total_size - buf->bytes_used; +@@ -89,36 +49,27 @@ static bool buffer_has_space(const Buffer *buf, size_t desired_length) + return desired_length <= bytes_remaining; + } + +-/* buffer grow */ +-static int buffer_grow(Buffer *buf, size_t minimum_size) ++static int buffer_grow(isula_buffer *buf, size_t minimum_size) + { +- size_t factor = 0; +- size_t new_size = 0; ++ size_t factor, new_size; + char *tmp = NULL; + +- if (buf == NULL) { +- return -1; +- } +- + factor = buf->total_size; + if (factor < minimum_size) { + factor = minimum_size; + } + +- if (factor > SIZE_MAX / 2) { ++ if (factor == 0) { ++ ERROR("Invalid grow size"); + return -1; + } + +- new_size = factor * 2; +- if (new_size == 0) { +- return -1; +- } +- +- tmp = lcr_util_common_calloc_s(new_size); ++ tmp = lcr_util_smart_calloc_s(factor, 2); + if (tmp == NULL) { + ERROR("Out of memory"); + return -1; + } ++ new_size = factor * 2; + + (void)memcpy(tmp, buf->contents, buf->total_size); + +@@ -129,14 +80,9 @@ static int buffer_grow(Buffer *buf, size_t minimum_size) + return 0; + } + +-/* buffer cat */ +-static void buffer_cat(Buffer *buf, const char *append, size_t length) ++static void buffer_cat(isula_buffer *buf, const char *append, size_t length) + { +- size_t i = 0; +- +- if (buf == NULL) { +- return; +- } ++ size_t i; + + for (i = 0; i < length; i++) { + if (append[i] == '\0') { +@@ -150,13 +96,12 @@ static void buffer_cat(Buffer *buf, const char *append, size_t length) + *(buf->contents + buf->bytes_used) = '\0'; + } + +-/* buffer append */ +-static int buffer_append(Buffer *buf, const char *append, size_t length) ++static int buffer_append(isula_buffer *buf, const char *append, size_t length) + { + size_t desired_length = 0; + +- if (buf == NULL) { +- return -1; ++ if (append == NULL) { ++ return 0; + } + + desired_length = length + 1; +@@ -171,62 +116,132 @@ static int buffer_append(Buffer *buf, const char *append, size_t length) + return 0; + } + +-/* buffer nappendf */ +-int buffer_nappendf(Buffer *buf, size_t length, const char *format, ...) ++int isula_buffer_nappend(isula_buffer *buf, size_t length, const char *format, ...) + { + int status = 0; +- size_t printf_length = 0; ++ size_t printf_length; + __isula_auto_free char *tmp = NULL; + va_list argp; + + if (buf == NULL) { ++ DEBUG("Empty buffer."); + return -1; + } + +- if (length > SIZE_MAX / sizeof(char) - 1) { ++ if (format == NULL || length == 0) { ++ return 0; ++ } ++ ++ if (length > SIZE_MAX - 1) { ++ ERROR("Too large append string"); + return -1; + } + printf_length = length + 1; +- tmp = calloc(1, printf_length * sizeof(char)); ++ tmp = lcr_util_smart_calloc_s(sizeof(char), printf_length); + if (tmp == NULL) { ++ ERROR("Out of memory"); + return -1; + } + + va_start(argp, format); +- status = vsnprintf(tmp, length, format, argp); ++ status = vsnprintf(tmp, printf_length, format, argp); + va_end(argp); + if (status < 0) { ++ SYSERROR("Sprintf error"); + return -1; + } + +- status = buffer_append(buf, tmp, length); +- if (status != 0) { ++ return buffer_append(buf, tmp, length); ++} ++ ++int isula_buffer_append(isula_buffer *buf, const char *str) ++{ ++ if (buf == NULL) { ++ DEBUG("Empty buffer."); + return -1; + } + +- return 0; ++ if (str == NULL || strlen(str) == 0) { ++ return 0; ++ } ++ ++ return buffer_append(buf, str, strlen(str)); + } + +-/* buffer to string */ +-char *buffer_to_s(const Buffer *buf) ++char *isula_buffer_to_str(const isula_buffer *buf) + { + size_t len; + char *result = NULL; + + if (buf == NULL) { ++ DEBUG("Empty argument."); + return NULL; + } + +- len = buffer_strlen(buf); ++ len = buf->bytes_used; + if (len == SIZE_MAX) { ++ ERROR("Too large buffer data"); + return NULL; + } + +- result = calloc(1, len + 1); ++ result = lcr_util_smart_calloc_s(1, len + 1); + if (result == NULL) { ++ ERROR("Out of memory"); + return NULL; + } + (void)strncpy(result, buf->contents, len); + + return result; + } ++ ++size_t isula_buffer_strlen(const isula_buffer *buf) ++{ ++ return buf == NULL ? 0 : buf->bytes_used; ++} ++ ++isula_buffer *isula_buffer_alloc(size_t initial_size) ++{ ++ isula_buffer *buf = NULL; ++ char *tmp = NULL; ++ ++ if (initial_size == 0) { ++ return NULL; ++ } ++ ++ buf = lcr_util_common_calloc_s(sizeof(isula_buffer)); ++ if (buf == NULL) { ++ ERROR("Out of memory"); ++ return NULL; ++ } ++ ++ tmp = lcr_util_smart_calloc_s(1, initial_size); ++ if (tmp == NULL) { ++ ERROR("Out of memory"); ++ free(buf); ++ return NULL; ++ } ++ ++ buf->contents = tmp; ++ buf->bytes_used = 0; ++ buf->total_size = initial_size; ++ ++ buf->clear = isula_buffer_clear; ++ buf->nappend = isula_buffer_nappend; ++ buf->append = isula_buffer_append; ++ buf->to_str = isula_buffer_to_str; ++ buf->length = isula_buffer_strlen; ++ ++ return buf; ++} ++ ++void isula_buffer_free(isula_buffer *buf) ++{ ++ if (buf == NULL) { ++ return; ++ } ++ free(buf->contents); ++ buf->contents = NULL; ++ buf->bytes_used = 0; ++ buf->total_size = 0; ++ free(buf); ++} +\ No newline at end of file +diff --git a/src/utils/utils_buffer.h b/src/utils/utils_buffer.h +new file mode 100644 +index 0000000..22c975c +--- /dev/null ++++ b/src/utils/utils_buffer.h +@@ -0,0 +1,93 @@ ++/****************************************************************************** ++ * lcr: utils library for iSula ++ * ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. ++ * ++ * Authors: ++ * Haozi007 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ********************************************************************************/ ++ ++#ifndef _ISULA_UTILS_BUFFER_H ++#define _ISULA_UTILS_BUFFER_H ++ ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++struct __isula_buffer; ++ ++/* ++ * clear used data in buffer, and reset used_size to 0 ++ */ ++typedef void (*clear_op)(struct __isula_buffer *buf); ++ ++/* ++* append string which length is length into buffer; ++* length should >= strlen(formatted string), else will truncate format string; ++* success, return 0; ++* fail, return -1; ++*/ ++typedef int (*nappend_op)(struct __isula_buffer *buf, size_t length, const char *format, ...); ++ ++/* ++* append string into buffer; ++* success, return 0; ++* fail, return -1; ++*/ ++typedef int (*append_op)(struct __isula_buffer *buf, const char *str); ++ ++/* ++* transform buffer to string, and return to caller ++*/ ++typedef char *(*to_str_op)(const struct __isula_buffer *buf); ++ ++/* ++* get length of data in buffer ++*/ ++typedef size_t (*length_op)(const struct __isula_buffer *buf); ++ ++struct __isula_buffer { ++ char *contents; ++ size_t bytes_used; ++ size_t total_size; ++ clear_op clear; ++ nappend_op nappend; ++ append_op append; ++ to_str_op to_str; ++ length_op length; ++}; ++typedef struct __isula_buffer isula_buffer; ++ ++/* ++* create isula buffer with initial size memory ++* if initial_size == 0, will return NULL; ++* if success, return a isula_buffer struct; ++*/ ++isula_buffer *isula_buffer_alloc(size_t initial_size); ++ ++/* ++* free isula_buffer struct and memory in it ++*/ ++void isula_buffer_free(isula_buffer *buf); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +\ No newline at end of file +diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt +index 4c66a98..ff0ca47 100644 +--- a/tests/CMakeLists.txt ++++ b/tests/CMakeLists.txt +@@ -26,29 +26,52 @@ find_package(GTest REQUIRED) + configure_file("data/ocihook.json" ${CMAKE_BINARY_DIR}/tests/ocihook.json COPYONLY) + configure_file("data/process.json" ${CMAKE_BINARY_DIR}/tests/process.json COPYONLY) + ++file(GLOB_RECURSE test_util_srcs ++ "${CMAKE_SOURCE_DIR}/src/third_party/*.c" ++ "${CMAKE_SOURCE_DIR}/src/third_party/**/*.c" ++ "${CMAKE_SOURCE_DIR}/src/json/*.c" ++ "${CMAKE_SOURCE_DIR}/src/json/**/*.c" ++ "${CMAKE_SOURCE_DIR}/src/utils/*.c" ++ "${CMAKE_SOURCE_DIR}/src/utils/**/*.c" ++ "${CMAKE_BINARY_DIR}/json/*.c" ++) ++ ++add_library(test_libisula_utils SHARED ${test_util_srcs}) ++target_include_directories(test_libisula_utils ++ PUBLIC ${CMAKE_SOURCE_DIR}/src ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/utils ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party/libocispec ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/json ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/json/schema/src ++ PUBLIC ${CMAKE_BINARY_DIR}/json ++ PUBLIC ${CMAKE_BINARY_DIR}/conf ++ ) ++target_link_libraries(test_libisula_utils ${LIBYAJL_LIBRARY}) ++ + macro(_DEFINE_NEW_TEST) + add_executable(${ARGV0} +- ${TESTS_UTILS_SRCS} + main.cpp + ${ARGV0}.cpp + ) + + target_link_libraries(${ARGV0} +- isula_libutils ++ test_libisula_utils + ${GTEST_LIBRARY} +- ${LIBYAJL_LIBRARY} + pthread + ) + + target_include_directories(${ARGV0} PUBLIC + ${GTEST_INCLUDE_DIR} +- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${CMAKE_SOURCE_DIR}/src ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/utils + PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party ++ PUBLIC ${CMAKE_SOURCE_DIR}/src/third_party/libocispec + PUBLIC ${CMAKE_SOURCE_DIR}/src/json + PUBLIC ${CMAKE_SOURCE_DIR}/src/json/schema/src + PUBLIC ${CMAKE_BINARY_DIR}/json + PUBLIC ${CMAKE_BINARY_DIR}/conf ++ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + ) + + add_test( +@@ -72,7 +95,7 @@ _DEFINE_NEW_TEST(libocispec_ut libocispec_testcase) + _DEFINE_NEW_TEST(defs_process_ut defs_process_testcase) + _DEFINE_NEW_TEST(go_crc64_ut go_crc64_testcase) + _DEFINE_NEW_TEST(auto_cleanup_ut autocleanup_testcase) +- ++_DEFINE_NEW_TEST(utils_buffer_ut isula_buffer_testcase) + + # mock test for run lcov to generate html + add_executable(mock_ut main.cpp) +@@ -84,7 +107,7 @@ target_link_libraries(mock_ut + ${GTEST_LIBRARY} + pthread + ) +-add_dependencies(mock_ut log_ut libocispec_ut defs_process_ut go_crc64_ut) ++add_dependencies(mock_ut log_ut libocispec_ut defs_process_ut go_crc64_ut auto_cleanup_ut utils_buffer_ut) + + IF(ENABLE_GCOV) + add_custom_target(coverage +diff --git a/tests/auto_cleanup_ut.cpp b/tests/auto_cleanup_ut.cpp +index 1eff4b2..b167bcb 100644 +--- a/tests/auto_cleanup_ut.cpp ++++ b/tests/auto_cleanup_ut.cpp +@@ -105,16 +105,34 @@ TEST(autocleanup_testcase, test__isula_auto_prw_unlock) + size_t do_auto_free() + { + __isula_auto_free void *test = nullptr; ++#if defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33)) ++ struct mallinfo2 info = { 0 }; ++ ++ // use 1024 * 1024 to ensure memory allo from mmap ++ test = malloc(1024 * 1024); ++ info = mallinfo2(); ++ return info.hblks; ++#else + struct mallinfo info = { 0 }; + + // use 1024 * 1024 to ensure memory allo from mmap + test = malloc(1024 * 1024); + info = mallinfo(); + return info.hblks; ++#endif + } + + TEST(autocleanup_testcase, test__isula_auto_free) + { ++#if defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33)) ++ struct mallinfo2 before; ++ struct mallinfo2 after; ++ size_t used; ++ ++ before = mallinfo2(); ++ used = do_auto_free(); ++ after = mallinfo2(); ++#else + struct mallinfo before; + struct mallinfo after; + size_t used; +@@ -122,6 +140,7 @@ TEST(autocleanup_testcase, test__isula_auto_free) + before = mallinfo(); + used = do_auto_free(); + after = mallinfo(); ++#endif + ASSERT_EQ(0, after.hblks); + ASSERT_NE(used, after.hblks); + ASSERT_NE(used, before.hblks); +diff --git a/tests/utils_buffer_ut.cpp b/tests/utils_buffer_ut.cpp +new file mode 100644 +index 0000000..3cc95a6 +--- /dev/null ++++ b/tests/utils_buffer_ut.cpp +@@ -0,0 +1,213 @@ ++/****************************************************************************** ++ * iSula-libutils: ut for utils_buffer.c ++ * ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. ++ * ++ * Authors: ++ * Haozi007 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ********************************************************************************/ ++ ++#include ++ ++#include ++#include ++ ++#include "utils_buffer.h" ++ ++TEST(isula_buffer_testcase, test__isula_buffer_alloc) ++{ ++ isula_buffer *ib = nullptr; ++ ++ ib = isula_buffer_alloc(0); ++ ASSERT_EQ(ib, nullptr); ++ ++ ib = isula_buffer_alloc(SIZE_MAX); ++ ASSERT_EQ(ib, nullptr); ++ ++ ib = isula_buffer_alloc(1); ++ ASSERT_NE(ib, nullptr); ++ ASSERT_NE(ib->contents, nullptr); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ASSERT_EQ(ib->total_size, 1); ++ ++ isula_buffer_free(ib); ++ ib = nullptr; ++ ++ // check nullptr input, donot coredump ++ isula_buffer_free(ib); ++} ++ ++TEST(isula_buffer_testcase, test__isula_buffer_nappend) ++{ ++ isula_buffer *ib = nullptr; ++ int ret; ++ const size_t initSize = 8; ++ ++ ib = isula_buffer_alloc(initSize); ++ ASSERT_NE(ib, nullptr); ++ ASSERT_NE(ib->contents, nullptr); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ASSERT_EQ(ib->total_size, initSize); ++ ++ ret = ib->nappend(nullptr, 1, "hello"); ++ ASSERT_NE(ret, 0); ++ ret = ib->nappend(ib, SIZE_MAX, "hello"); ++ ASSERT_NE(ret, 0); ++ ret = ib->nappend(ib, 0, "hello"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ret = ib->nappend(ib, 1, nullptr); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ret = ib->nappend(ib, 6, "hello"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 5); ++ ASSERT_EQ(ib->total_size, initSize); ++ ASSERT_STREQ(ib->contents, "hello"); ++ ret = ib->nappend(ib, 7, " world"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 11); ++ ASSERT_EQ(ib->total_size, initSize * 2); ++ ASSERT_STREQ(ib->contents, "hello world"); ++ ++ ib->clear(ib); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ++ ret = ib->nappend(ib, 10, "hello %s", "world"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 10); ++ ASSERT_EQ(ib->total_size, initSize * 2); ++ ASSERT_STREQ(ib->contents, "hello worl"); ++ ++ isula_buffer_free(ib); ++ ib = nullptr; ++} ++ ++ ++TEST(isula_buffer_testcase, test__isula_buffer_append) ++{ ++ isula_buffer *ib = nullptr; ++ int ret; ++ const size_t initSize = 8; ++ ++ ib = isula_buffer_alloc(initSize); ++ ASSERT_NE(ib, nullptr); ++ ASSERT_NE(ib->contents, nullptr); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ASSERT_EQ(ib->total_size, initSize); ++ ++ ret = ib->append(nullptr, "hello"); ++ ASSERT_NE(ret, 0); ++ ret = ib->append(ib, nullptr); ++ ASSERT_EQ(ret, 0); ++ ret = ib->append(ib, ""); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ret = ib->append(ib, "hello"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 5); ++ ASSERT_EQ(ib->total_size, initSize); ++ ASSERT_STREQ(ib->contents, "hello"); ++ ret = ib->append(ib, " world"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 11); ++ ASSERT_EQ(ib->total_size, initSize * 2); ++ ASSERT_STREQ(ib->contents, "hello world"); ++ ++ isula_buffer_free(ib); ++ ib = nullptr; ++} ++ ++TEST(isula_buffer_testcase, test__isula_buffer_to_str) ++{ ++ isula_buffer *ib = nullptr; ++ int ret; ++ const size_t initSize = 8; ++ char *tmpStr = nullptr; ++ ++ ib = isula_buffer_alloc(initSize); ++ ASSERT_NE(ib, nullptr); ++ ASSERT_NE(ib->contents, nullptr); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ASSERT_EQ(ib->total_size, initSize); ++ ++ tmpStr = ib->to_str(nullptr); ++ ASSERT_EQ(tmpStr, nullptr); ++ tmpStr = ib->to_str(ib); ++ ASSERT_NE(tmpStr, nullptr); ++ ASSERT_STREQ(tmpStr, ""); ++ free(tmpStr); ++ ++ ret = ib->nappend(ib, 5, "hello"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 5); ++ ASSERT_EQ(ib->total_size, initSize); ++ ASSERT_STREQ(ib->contents, "hello"); ++ tmpStr = ib->to_str(ib); ++ ASSERT_NE(tmpStr, nullptr); ++ ASSERT_STREQ(tmpStr, "hello"); ++ free(tmpStr); ++ ++ ret = ib->nappend(ib, 6, " world"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 11); ++ ASSERT_EQ(ib->total_size, initSize * 2); ++ ASSERT_STREQ(ib->contents, "hello world"); ++ tmpStr = ib->to_str(ib); ++ ASSERT_NE(tmpStr, nullptr); ++ ASSERT_STREQ(tmpStr, "hello world"); ++ free(tmpStr); ++ ++ isula_buffer_free(ib); ++ ib = nullptr; ++} ++ ++TEST(isula_buffer_testcase, test__isula_buffer_clear) ++{ ++ isula_buffer *ib = nullptr; ++ int ret; ++ const size_t initSize = 8; ++ char *tmpStr = nullptr; ++ ++ ib = isula_buffer_alloc(initSize); ++ ASSERT_NE(ib, nullptr); ++ ASSERT_NE(ib->contents, nullptr); ++ ASSERT_EQ(ib->bytes_used, 0); ++ ASSERT_EQ(ib->total_size, initSize); ++ ++ ret = ib->nappend(ib, 5, "hello"); ++ ASSERT_EQ(ret, 0); ++ ASSERT_EQ(ib->bytes_used, 5); ++ ASSERT_EQ(ib->length(ib), 5); ++ ASSERT_EQ(ib->total_size, initSize); ++ ASSERT_STREQ(ib->contents, "hello"); ++ tmpStr = ib->to_str(ib); ++ ASSERT_NE(tmpStr, nullptr); ++ ASSERT_STREQ(tmpStr, "hello"); ++ free(tmpStr); ++ ib->clear(ib); ++ ASSERT_NE(ib, nullptr); ++ ASSERT_NE(ib->contents, nullptr); ++ ASSERT_EQ(ib->length(ib), 0); ++ ASSERT_EQ(ib->total_size, initSize); ++ ++ ib->clear(nullptr); ++ ASSERT_EQ(ib->length(nullptr), 0); ++ ++ isula_buffer_free(ib); ++ ib = nullptr; ++} +\ No newline at end of file +-- +2.34.1 + diff --git a/0006-264-Support-both-C-11-and-C-17.patch b/0006-264-Support-both-C-11-and-C-17.patch new file mode 100644 index 0000000..b616693 --- /dev/null +++ b/0006-264-Support-both-C-11-and-C-17.patch @@ -0,0 +1,34 @@ +From 2d3f4ef95a3c4d4e87ce71c5ced43f3d8e81cc9e Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Thu, 14 Sep 2023 09:00:05 +0000 +Subject: [PATCH 6/8] !264 Support both C++11 and C++17 * Support both C++11 + and C++17 + +--- + cmake/set_build_flags.cmake | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/cmake/set_build_flags.cmake b/cmake/set_build_flags.cmake +index 3b6842a..7d4c9fc 100644 +--- a/cmake/set_build_flags.cmake ++++ b/cmake/set_build_flags.cmake +@@ -24,8 +24,15 @@ + set(CMAKE_C_FLAGS "-fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -Wall -fPIE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'") + ++include(CheckCXXCompilerFlag) ++CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17) + if (ENABLE_UT) +- set(CMAKE_CXX_FLAGS "-fPIC -std=c++11 -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -Wall") ++ set(CMAKE_CXX_VERSION "-std=c++11") ++ if (COMPILER_SUPPORTS_CXX17) ++ message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has C++17 support.") ++ set(CMAKE_CXX_VERSION "-std=c++17") ++ endif() ++ set(CMAKE_CXX_FLAGS "-fPIC ${CMAKE_CXX_VERSION} -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'") + endif() + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-E -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines -shared -pthread") +-- +2.34.1 + diff --git a/0007-262-Fix-empty-pointer-and-overflow.patch b/0007-262-Fix-empty-pointer-and-overflow.patch new file mode 100644 index 0000000..04d758a --- /dev/null +++ b/0007-262-Fix-empty-pointer-and-overflow.patch @@ -0,0 +1,1283 @@ +From ff5ccbd62e0e01a4e246b5b3c7b62a9703091bd6 Mon Sep 17 00:00:00 2001 +From: jake +Date: Fri, 15 Sep 2023 01:50:29 +0000 +Subject: [PATCH 7/8] !262 Fix empty pointer and overflow * Fix empty pointer + and overflow + +--- + src/runtime/conf.c | 63 +++++++++-- + src/runtime/lcrcontainer.c | 135 ++--------------------- + src/runtime/lcrcontainer.h | 40 ------- + src/runtime/lcrcontainer_execute.c | 30 ++++++ + src/runtime/lcrcontainer_extend.c | 144 ++++--------------------- + src/runtime/lcrcontainer_extend.h | 11 -- + src/third_party/go_crc64.c | 6 +- + src/third_party/libocispec/common_c.py | 116 +++++++++++++------- + src/third_party/libocispec/common_h.py | 4 +- + src/third_party/libocispec/sources.py | 51 +++++---- + src/utils/utils_buffer.c | 4 + + src/utils/utils_cgroup.c | 5 + + tests/fuzz/log_fuzz.cc | 2 +- + 13 files changed, 238 insertions(+), 373 deletions(-) + +diff --git a/src/runtime/conf.c b/src/runtime/conf.c +index d505507..7739de6 100644 +--- a/src/runtime/conf.c ++++ b/src/runtime/conf.c +@@ -642,6 +642,10 @@ static int trans_oci_process_prlimit(const defs_process *proc, struct lcr_list * + + for (i = 0; i < proc->rlimits_len; i++) { + defs_process_rlimits_element *lr = proc->rlimits[i]; ++ if (lr == NULL) { ++ continue; ++ } ++ + char buf_key[30] = { 0 }; + char buf_value[60] = { 0 }; + size_t j; +@@ -754,6 +758,10 @@ struct lcr_list *trans_oci_process(const defs_process *proc) + { + struct lcr_list *conf = NULL; + ++ if (proc == NULL) { ++ return NULL; ++ } ++ + conf = lcr_util_common_calloc_s(sizeof(struct lcr_list)); + if (conf == NULL) { + return NULL; +@@ -1097,7 +1105,8 @@ bool is_system_container(const oci_runtime_spec *container) + { + size_t i = 0; + for (i = 0; container->annotations != NULL && i < container->annotations->len; i++) { +- if (strcmp(container->annotations->keys[i], "system.container") == 0) { ++ if (container->annotations->keys[i] != NULL && ++ strcmp(container->annotations->keys[i], "system.container") == 0) { + return true; + } + } +@@ -1108,7 +1117,8 @@ static bool is_external_rootfs(const oci_runtime_spec *container) + { + size_t i = 0; + for (i = 0; container->annotations != NULL && i < container->annotations->len; i++) { +- if (strcmp(container->annotations->keys[i], "external.rootfs") == 0) { ++ if (container->annotations->keys[i] != NULL && ++ strcmp(container->annotations->keys[i], "external.rootfs") == 0) { + return true; + } + } +@@ -1170,8 +1180,14 @@ struct lcr_list *trans_oci_mounts(const oci_runtime_spec *c) + struct lcr_list *node = NULL; + defs_mount *tmp = NULL; + size_t i; +- bool system_container = is_system_container(c); +- bool external_rootfs = is_external_rootfs(c); ++ bool system_container = false; ++ bool external_rootfs = false; ++ ++ if (c == NULL) { ++ return NULL; ++ } ++ system_container = is_system_container(c); ++ external_rootfs = is_external_rootfs(c); + + conf = lcr_util_common_calloc_s(sizeof(*conf)); + if (conf == NULL) { +@@ -1181,7 +1197,7 @@ struct lcr_list *trans_oci_mounts(const oci_runtime_spec *c) + + for (i = 0; i < c->mounts_len; i++) { + tmp = c->mounts[i]; +- if (tmp->type == NULL) { ++ if (tmp == NULL || tmp->type == NULL) { + goto out_free; + } + +@@ -1210,6 +1226,10 @@ static int trans_one_oci_id_mapping(struct lcr_list *conf, const char *typ, cons + char buf_value[DEFAULT_BUF_LEN] = { 0 }; + char subid[ID_MAP_LEN] = { 0 }; + ++ if (id == NULL) { ++ return -1; ++ } ++ + nret = snprintf(buf_value, sizeof(buf_value), "%s %u %u %u", typ, id->container_id, id->host_id, id->size); + if (nret < 0 || (size_t)nret >= sizeof(buf_value)) { + return -1; +@@ -1573,6 +1593,10 @@ static int trans_resources_devices_v1(const defs_resources *res, struct lcr_list + + for (i = 0; i < res->devices_len; i++) { + defs_device_cgroup *lrd = res->devices[i]; ++ if (lrd == NULL) { ++ continue; ++ } ++ + if (trans_resources_devices_ret(lrd, buf_value, sizeof(buf_value)) < 0) { + goto out; + } +@@ -2009,6 +2033,10 @@ static int trans_resources_devices_v2(const defs_resources *res, struct lcr_list + + for (i = 0; i < res->devices_len; i++) { + defs_device_cgroup *lrd = res->devices[i]; ++ if (lrd == NULL) { ++ continue; ++ } ++ + if (trans_resources_devices_ret(lrd, buf_value, sizeof(buf_value)) < 0) { + goto out; + } +@@ -2491,7 +2519,7 @@ static struct lcr_list *trans_oci_namespaces(const oci_runtime_config_linux *l) + char *ns_name = NULL; + ns = l->namespaces[i]; + +- if (ns->type == NULL || ns->path == NULL) { ++ if (ns == NULL || ns->type == NULL || ns->path == NULL) { + continue; + } + +@@ -2808,6 +2836,12 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, isula_buff + ret = -1; + goto out; + } ++ ++ if (strlen(syscall->names[i]) > SIZE_MAX - strlen(action) - 2) { ++ ERROR("Out of range"); ++ ret = -1; ++ goto out; ++ } + if (buffer->nappend(buffer, strlen(syscall->names[i]) + strlen(action) + 2, "%s %s", syscall->names[i], action)) { + ERROR("Failed to append syscall name and action\n"); + ret = -1; +@@ -2820,6 +2854,15 @@ static int seccomp_append_rule(const defs_syscall *syscall, size_t i, isula_buff + ret = -1; + goto out; + } ++ ++ /* Appending content is syscall->args[j]->op plus ++ * three unsigned numbers(which length is no more than 20 * 3) ++ */ ++ if (strlen(syscall->args[j]->op) > SIZE_MAX - 20 * 3) { ++ ERROR("Out of range"); ++ ret = -1; ++ goto out; ++ } + if (buffer->nappend(buffer, 20 * 3 + strlen(syscall->args[j]->op), " [%u,%llu,%s,%llu]", + syscall->args[j]->index, syscall->args[j]->value, syscall->args[j]->op, + syscall->args[j]->value_two)) { +@@ -3033,6 +3076,10 @@ struct lcr_list *trans_oci_linux(const oci_runtime_config_linux *l, char **secco + int ret = 0; + struct lcr_list *tmp = NULL; + ++ if (l == NULL) { ++ return NULL; ++ } ++ + struct lcr_list *conf = lcr_util_common_calloc_s(sizeof(*conf)); + if (conf == NULL) { + return NULL; +@@ -3115,6 +3162,10 @@ struct lcr_list *trans_annotations(const json_map_string_string *anno) + size_t len; + int ret = 0; + ++ if (anno == NULL) { ++ return NULL; ++ } ++ + struct lcr_list *conf = lcr_util_common_calloc_s(sizeof(*conf)); + if (conf == NULL) { + return NULL; +diff --git a/src/runtime/lcrcontainer.c b/src/runtime/lcrcontainer.c +index ae5fe5b..4270902 100644 +--- a/src/runtime/lcrcontainer.c ++++ b/src/runtime/lcrcontainer.c +@@ -43,52 +43,6 @@ + #include "utils.h" + #include "oci_runtime_spec.h" + +-/* +- * Free lcr_container_info array returned by lcr_list_{active,all}_containers +- */ +-void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size) +-{ +- size_t i = 0; +- struct lcr_container_info *in = NULL; +- +- if (info_arr == NULL) { +- return; +- } +- if (size == 0) { +- return; +- } +- for (i = 0, in = *info_arr; i < size; i++, in++) { +- free(in->interface); +- free(in->ipv4); +- free(in->ipv6); +- free(in->name); +- free(in->state); +- } +- free(*info_arr); +- *info_arr = NULL; +-} +- +-/* +- * Free lcr_container_info returned lcr_container_info_get +- */ +-void lcr_container_info_free(struct lcr_container_info *info) +-{ +- if (info == NULL) { +- return; +- } +- free(info->interface); +- info->interface = NULL; +- free(info->ipv4); +- info->ipv4 = NULL; +- free(info->ipv6); +- info->ipv6 = NULL; +- free(info->name); +- info->name = NULL; +- free(info->state); +- info->state = NULL; +- free(info); +-} +- + static inline bool is_container_exists(struct lxc_container *c) + { + return c->is_defined(c); +@@ -99,85 +53,6 @@ static inline bool is_container_can_control(struct lxc_container *c) + return c->may_control(c); + } + +-/* +- * Get one container info for a given name and lcrpath. +- * return struct of container info, or NULL on error. +- */ +-struct lcr_container_info *lcr_container_info_get(const char *name, const char *lcrpath) +-{ +- int nret = -1; +- struct lcr_container_info *info = NULL; +- const char *st = NULL; +- bool run_flag = false; +- +- struct lxc_container *c = lxc_container_without_config_new(name, lcrpath); +- if (c == NULL) { +- return NULL; +- } +- +- if (!is_container_exists(c)) { +- goto put_and_finish; +- } +- +- st = c->state(c); +- if (st == NULL) { +- st = "UNKNOWN"; +- } +- run_flag = (strcmp(st, "STOPPED") != 0); +- +- /* Now it makes sense to allocate memory */ +- info = lcr_util_common_calloc_s(sizeof(*info)); +- if (info == NULL) { +- nret = -1; +- goto put_and_finish; +- } +- info->init = -1; +- info->running = run_flag; +- info->name = lcr_util_strdup_s(name); +- info->state = lcr_util_strdup_s(st); +- if (run_flag) { +- info->init = c->init_pid(c); +- } +- +- nret = 0; +-put_and_finish: +- lxc_container_put(c); +- if (nret != 0) { +- lcr_container_info_free(info); +- info = NULL; +- } +- return info; +-} +- +-/* +- * Get a complete list of all containers for a given lcrpath. +- * return Number of containers, or -1 on error. +- **/ +-int lcr_list_all_containers(const char *lcrpath, struct lcr_container_info **info_arr) +-{ +- char **container = NULL; +- int n = 0; +- int nret = -1; +- size_t info_size = 0; +- const char *path = lcrpath ? lcrpath : LCRPATH; +- +- clear_error_message(&g_lcr_error); +- n = list_all_containers(path, &container, NULL); +- if (n == -1) { +- n = 0; +- } +- +- nret = lcr_containers_info_get(path, info_arr, &info_size, container, n); +- if (info_arr == NULL && nret == 0) { +- return -1; +- } else if (info_arr == NULL || nret == -1) { +- lcr_containers_info_free(info_arr, info_size); +- return -1; +- } +- +- return (int)info_size; +-} +- + static int create_partial(const struct lxc_container *c) + { + int fd = 0; +@@ -275,6 +150,16 @@ bool lcr_create(const char *name, const char *lcrpath, void *oci_config) + const char *tmp_path = lcrpath ? lcrpath : LCRPATH; + oci_runtime_spec *oci_spec = (oci_runtime_spec *)oci_config; + ++ if (name == NULL) { ++ ERROR("Missing container name"); ++ return false; ++ } ++ ++ if (oci_spec == NULL) { ++ ERROR("Empty oci config"); ++ return false; ++ } ++ + clear_error_message(&g_lcr_error); + isula_libutils_set_log_prefix(name); + +diff --git a/src/runtime/lcrcontainer.h b/src/runtime/lcrcontainer.h +index 6add8c4..d4cef39 100644 +--- a/src/runtime/lcrcontainer.h ++++ b/src/runtime/lcrcontainer.h +@@ -46,24 +46,6 @@ __EXPORT__ struct lcr_console_config { + char *log_file_size; + }; + +-/* +-* Store lcr container info +-*/ +-__EXPORT__ struct lcr_container_info { +- /* Name of container. */ +- char *name; +- /* State of container. */ +- char *state; +- /* Interface of container. */ +- char *interface; +- char *ipv4; +- char *ipv6; +- pid_t init; +- double ram; +- double swap; +- bool running; +-}; +- + __EXPORT__ struct blkio_stats { + uint64_t read; + uint64_t write; +@@ -132,28 +114,6 @@ __EXPORT__ struct lcr_cgroup_resources { + int64_t cpurt_runtime; + }; + +-/* +-* Get one container info for a given lcrpath. +-* return struct of container info, or NULL on error. +-*/ +-__EXPORT__ struct lcr_container_info *lcr_container_info_get(const char *name, const char *lcrpath); +- +-/* +-* Free lcr_container_info returned lcr_container_info_get +-*/ +-__EXPORT__ void lcr_container_info_free(struct lcr_container_info *info); +- +-/* +-* Get a complete list of all containers for a given lcrpath. +-* return Number of containers, or -1 on error. +-*/ +-__EXPORT__ int lcr_list_all_containers(const char *lcrpath, struct lcr_container_info **info_arr); +- +-/* +-* Free lcr_container_info array returned by lcr_list_{active,all}_containers +-*/ +-__EXPORT__ void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size); +- + /* + * Create a container + * param name : container name +diff --git a/src/runtime/lcrcontainer_execute.c b/src/runtime/lcrcontainer_execute.c +index e91ff27..61bcd84 100644 +--- a/src/runtime/lcrcontainer_execute.c ++++ b/src/runtime/lcrcontainer_execute.c +@@ -736,6 +736,11 @@ bool do_update(struct lxc_container *c, const char *name, const char *lcrpath, s + { + bool bret = false; + ++ if (c == NULL) { ++ ERROR("Invalid arg c"); ++ return bret; ++ } ++ + // If container is not running, update config file is enough, + // resources will be updated when the container is started again. + // If container is running (including paused), we need to update configs +@@ -760,6 +765,16 @@ void do_lcr_state(struct lxc_container *c, struct lcr_container_state *lcs) + { + struct lxc_container_metrics lxc_metrics = { 0 }; + ++ if (c == NULL) { ++ ERROR("Invalid argument c"); ++ return; ++ } ++ ++ if (lcs == NULL) { ++ ERROR("Invalid argument lcs"); ++ return; ++ } ++ + clear_error_message(&g_lcr_error); + (void)memset(lcs, 0x00, sizeof(struct lcr_container_state)); + +@@ -915,6 +930,16 @@ bool do_attach(const char *name, const char *path, const struct lcr_exec_request + int pipefd[2] = {-1, -1}; + int status = 0; + ++ if (request == NULL) { ++ ERROR("Invalid request"); ++ return false; ++ } ++ ++ if (exit_code == NULL) { ++ ERROR("Invalid exit code"); ++ return false; ++ } ++ + if (pipe(pipefd) != 0) { + ERROR("Failed to create pipe\n"); + return false; +@@ -978,6 +1003,11 @@ void execute_lxc_start(const char *name, const char *path, const struct lcr_star + size_t i = 0; + int nret = 0; + ++ if (request == NULL) { ++ COMMAND_ERROR("Invalid request"); ++ exit(EXIT_FAILURE); ++ } ++ + if (lcr_util_check_inherited(true, -1) != 0) { + COMMAND_ERROR("Close inherited fds failed"); + } +diff --git a/src/runtime/lcrcontainer_extend.c b/src/runtime/lcrcontainer_extend.c +index 8b5a85c..d6b44d1 100644 +--- a/src/runtime/lcrcontainer_extend.c ++++ b/src/runtime/lcrcontainer_extend.c +@@ -425,74 +425,6 @@ cleanup: + return NULL; + } + +-static struct lcr_container_info *info_new(struct lcr_container_info **info, size_t *size) +-{ +- struct lcr_container_info *m = NULL; +- struct lcr_container_info *n = NULL; +- size_t length = 0; +- int nret = 0; +- +- if (*size > SIZE_MAX / sizeof(struct lcr_container_info) - 1) { +- return NULL; +- } +- +- length = (*size + 1) * sizeof(struct lcr_container_info); +- +- nret = lcr_mem_realloc((void **)&n, length, (void *)(*info), (*size) * sizeof(struct lcr_container_info)); +- if (nret < 0) { +- return NULL; +- } +- +- *info = n; +- m = *info + *size; +- (*size)++; +- +- // *INDENT-OFF* +- *m = (struct lcr_container_info) { +- .name = NULL, .state = NULL, .interface = NULL, .ipv4 = NULL, .ipv6 = NULL, .ram = 0.0, .swap = 0.0, .init = -1 +- }; +- // *INDENT-ON* +- return m; +-} +- +-static void free_arr(char **array, size_t size) +-{ +- size_t i; +- for (i = 0; i < size; i++) { +- free(array[i]); +- array[i] = NULL; +- } +- free(array); +-} +- +-/* +- * Get a complete list of active containers for a given lcrpath. +- * return Number of containers, or -1 on error. +- **/ +-int lcr_list_active_containers(const char *lcrpath, struct lcr_container_info **info_arr) +-{ +- char **c = NULL; +- int n = 0; +- int nret = -1; +- size_t info_size = 0; +- const char *path = lcrpath ? lcrpath : LCRPATH; +- +- n = list_active_containers(path, &c, NULL); +- if (n == -1) { +- n = 0; +- } +- +- nret = lcr_containers_info_get(path, info_arr, &info_size, c, n); +- if ((info_arr == NULL) && nret == 0) { +- return -1; +- } else if ((info_arr == NULL) || nret == -1) { +- lcr_containers_info_free(info_arr, info_size); +- return -1; +- } +- +- return (int)info_size; +-} +- + bool lcr_delete_with_force(const char *name, const char *lcrpath, bool force) + { + struct lxc_container *c = NULL; +@@ -563,61 +495,6 @@ void lcr_free_config(struct lcr_list *lcr_conf) + } + } + +-int lcr_containers_info_get(const char *lcrpath, struct lcr_container_info **info, size_t *size, char **containers, +- int num) +-{ +- struct lcr_container_info *in = NULL; +- struct lxc_container *c = NULL; +- int i; +- int nret = -1; +- +- if ((lcrpath == NULL) || num == 0) { +- goto err_out; +- } +- +- for (i = 0; i < num; i++) { +- const char *st = NULL; +- const char *name = containers[i]; +- bool run_flag = true; +- if (name == NULL) { +- continue; +- } +- +- c = lxc_container_without_config_new(name, lcrpath); +- if (c == NULL) { +- continue; +- } +- +- if (!c->is_defined(c)) { +- goto put_container; +- } +- +- st = c->state(c); +- if (st == NULL) { +- st = "UNKNOWN"; +- } +- run_flag = (strcmp(st, "STOPPED") != 0); +- +- /* Now it makes sense to allocate memory */ +- in = info_new(info, size); +- if (in == NULL) { +- goto put_container; +- } +- in->running = run_flag; +- in->name = lcr_util_strdup_s(name); +- in->state = lcr_util_strdup_s(st); +- if (run_flag) { +- in->init = c->init_pid(c); +- } +-put_container: +- lxc_container_put(c); +- } +- nret = 0; +-err_out: +- free_arr(containers, (size_t)num); +- return nret; +-} +- + /* + * Transform container JSON into oci_runtime_spec struct + */ +@@ -627,6 +504,11 @@ bool container_parse(const char *oci_filename, const char *oci_json_data, oci_ru + parser_error err = NULL; + bool ret = true; + ++ if (container == NULL) { ++ ERROR("Invalid container arg"); ++ return false; ++ } ++ + if (oci_json_data == NULL) { + *container = oci_runtime_spec_parse_file(oci_filename, &ctx, &err); + } else { +@@ -683,6 +565,11 @@ struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, oci_runtime_spec *co + { + struct lcr_list *lcr_conf = NULL; + ++ if (container == NULL) { ++ ERROR("Invalid arguments"); ++ return NULL; ++ } ++ + lcr_conf = lcr_util_common_calloc_s(sizeof(*lcr_conf)); + if (lcr_conf == NULL) { + goto out_free; +@@ -776,6 +663,10 @@ static char *escape_string_encode(const char *src) + return NULL; + } + ++ if (len > (SIZE_MAX - 1) / 2) { ++ return NULL; ++ } ++ + dst = lcr_util_common_calloc_s(2 * len + 1); + if (dst == NULL) { + ERROR("Out of memory"); +@@ -874,7 +765,7 @@ cleanup: + return ret; + } + +-char *lcr_get_bundle(const char *lcrpath, const char *name) ++static char *lcr_get_bundle(const char *lcrpath, const char *name) + { + size_t len = 0; + int nret = 0; +@@ -932,6 +823,11 @@ bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list + return bret; + } + ++ if (lcr_conf == NULL) { ++ ERROR("Empty lcr conf"); ++ return bret; ++ } ++ + bundle = lcr_get_bundle(path, name); + if (bundle == NULL) { + goto out_free; +diff --git a/src/runtime/lcrcontainer_extend.h b/src/runtime/lcrcontainer_extend.h +index 981a2bb..f524a4a 100644 +--- a/src/runtime/lcrcontainer_extend.h ++++ b/src/runtime/lcrcontainer_extend.h +@@ -44,12 +44,6 @@ struct lcr_list; + } \ + } while (0); + +-/* +- * Get a complete list of active containers for a given lcrpath. +- * return Number of containers, or -1 on error. +- */ +-int lcr_list_active_containers(const char *lcrpath, struct lcr_container_info **info_arr); +- + /* + * Delete a container + * param name : container name, required. +@@ -82,11 +76,6 @@ struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, oci_runtime_spec *co + */ + bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list *lcr_conf, const char *seccomp_conf); + +-int lcr_containers_info_get(const char *lcrpath, struct lcr_container_info **info, size_t *size, char **containers, +- int num); +- +-char *lcr_get_bundle(const char *lcrpath, const char *name); +- + bool translate_spec(const struct lxc_container *c, oci_runtime_spec *container); + + #ifdef __cplusplus +diff --git a/src/third_party/go_crc64.c b/src/third_party/go_crc64.c +index a08e07c..d680815 100644 +--- a/src/third_party/go_crc64.c ++++ b/src/third_party/go_crc64.c +@@ -32,10 +32,9 @@ isula_crc_table_t g_iso_crc_table; + static void make_table(isula_crc_table_t *tab, uint64_t poly) + { + uint64_t i, j; +- uint64_t t; + + for (i = 0; i < CRC_COL_LEN; i++) { +- t = i; ++ uint64_t t = i; + for (j = 0; j < CRC_ROW_LEN; j++) { + if ((t & 1) == 1) { + t = (t >> 1) ^ poly; +@@ -50,10 +49,9 @@ static void make_table(isula_crc_table_t *tab, uint64_t poly) + static void make_crc_table(isula_crc_table_t *tab) + { + uint64_t i, j; +- uint64_t crc; + + for (i = 0; i < CRC_COL_LEN; i++) { +- crc = tab->table[0][i]; ++ uint64_t crc = tab->table[0][i]; + for (j = 1; j < CRC_ROW_LEN; j++) { + crc = tab->table[0][(crc&0xff)] ^ (crc >> 8); + tab->table[j][i] = crc; +diff --git a/src/third_party/libocispec/common_c.py b/src/third_party/libocispec/common_c.py +index 8c4f92f..5d6ed70 100644 +--- a/src/third_party/libocispec/common_c.py ++++ b/src/third_party/libocispec/common_c.py +@@ -54,6 +54,14 @@ def generate_json_common_c(out): + + # define MAX_NUM_STR_LEN 21 + ++#if __WORDSIZE == 64 ++// current max user memory for 64-machine is 2^47 B ++#define MAX_MEMORY_SIZE ((size_t)1 << 47) ++#else ++// current max user memory for 32-machine is 2^31 B ++#define MAX_MEMORY_SIZE ((size_t)1 << 31) ++#endif ++ + static yajl_gen_status gen_yajl_val (yajl_val obj, yajl_gen g, parser_error *err); + + static yajl_gen_status gen_yajl_val_obj (yajl_val obj, yajl_gen g, parser_error *err) +@@ -227,15 +235,24 @@ safe_strdup(const char *src) + return dst; + } + +-void * +-safe_malloc(size_t size) +-{ ++void *smart_calloc(size_t count, size_t extra, size_t unit_size) { + void *ret = NULL; +- if (size == 0) +- abort(); +- ret = calloc(1, size); +- if (ret == NULL) +- abort(); ++ if (unit_size == 0) { ++ return NULL; ++ } ++ ++ if (extra > MAX_MEMORY_SIZE || count > MAX_MEMORY_SIZE - extra) { ++ return NULL; ++ } ++ ++ if (count + extra == 0 || count + extra > (MAX_MEMORY_SIZE / unit_size)) { ++ return NULL; ++ } ++ ++ ret = calloc(count + extra, unit_size); ++ if (ret == NULL) { ++ return NULL; ++ } + return ret; + } + +@@ -572,18 +589,18 @@ make_json_map_int_int (yajl_val src, const struct parser_context *ctx, + return NULL; + + len = YAJL_GET_OBJECT_NO_CHECK (src)->len; +- ret = calloc (1, sizeof (*ret)); ++ ret = smart_calloc (1, 0, sizeof (*ret)); + if (ret == NULL) + return NULL; + + ret->len = 0; +- ret->keys = calloc (len + 1, sizeof (int)); ++ ret->keys = smart_calloc (len, 1, sizeof (int)); + if (ret->keys == NULL) + { + return NULL; + } + +- ret->values = calloc (len + 1, sizeof (int)); ++ ret->values = smart_calloc (len, 1, sizeof (int)); + if (ret->values == NULL) + { + return NULL; +@@ -653,10 +670,10 @@ append_json_map_int_int (json_map_int_int * map, int key, int val) + return -1; + + len = map->len + 1; +- keys = calloc (1, len * sizeof (int)); ++ keys = smart_calloc (len, 0, sizeof (int)); + if (keys == NULL) + return -1; +- vals = calloc (1, len * sizeof (int)); ++ vals = smart_calloc (len, 0, sizeof (int)); + if (vals == NULL) + { + return -1; +@@ -760,16 +777,16 @@ make_json_map_int_bool (yajl_val src, const struct parser_context *ctx, + return NULL; + + len = YAJL_GET_OBJECT_NO_CHECK (src)->len; +- ret = calloc (1, sizeof (*ret)); ++ ret = smart_calloc (1, 0, sizeof (*ret)); + if (ret == NULL) + return NULL; + ret->len = 0; +- ret->keys = calloc (len + 1, sizeof (int)); ++ ret->keys = smart_calloc (len, 1, sizeof (int)); + if (ret->keys == NULL) + { + return NULL; + } +- ret->values = calloc (len + 1, sizeof (bool)); ++ ret->values = smart_calloc (len, 1, sizeof (bool)); + if (ret->values == NULL) + { + return NULL; +@@ -832,10 +849,10 @@ append_json_map_int_bool (json_map_int_bool * map, int key, bool val) + return -1; + + len = map->len + 1; +- keys = calloc (len, sizeof (int)); ++ keys = smart_calloc (len, 0, sizeof (int)); + if (keys == NULL) + return -1; +- vals = calloc (len, sizeof (bool)); ++ vals = smart_calloc (len, 0, sizeof (bool)); + if (vals == NULL) + { + return -1; +@@ -945,18 +962,18 @@ make_json_map_int_string (yajl_val src, const struct parser_context *ctx, + + len = YAJL_GET_OBJECT_NO_CHECK (src)->len; + +- ret = calloc (1, sizeof (*ret)); ++ ret = smart_calloc (1, 0, sizeof (*ret)); + if (ret == NULL) + return NULL; + + ret->len = 0; +- ret->keys = calloc (len + 1, sizeof (int)); ++ ret->keys = smart_calloc (len, 1, sizeof (int)); + if (ret->keys == NULL) + { + return NULL; + } + +- ret->values = calloc (len + 1, sizeof (char *)); ++ ret->values = smart_calloc (len, 1, sizeof (char *)); + if (ret->values == NULL) + { + return NULL; +@@ -1111,20 +1128,20 @@ make_json_map_string_int (yajl_val src, const struct parser_context *ctx, + return NULL; + + len = YAJL_GET_OBJECT_NO_CHECK (src)->len; +- ret = calloc (1, sizeof (*ret)); ++ ret = smart_calloc (1, 0, sizeof (*ret)); + if (ret == NULL) + { + *(err) = strdup ("error allocating memory"); + return NULL; + } + ret->len = 0; +- ret->keys = calloc (len + 1, sizeof (char *)); ++ ret->keys = smart_calloc (len, 1, sizeof (char *)); + if (ret->keys == NULL) + { + *(err) = strdup ("error allocating memory"); + return NULL; + } +- ret->values = calloc (len + 1, sizeof (int)); ++ ret->values = smart_calloc (len, 1, sizeof (int)); + if (ret->values == NULL) + { + *(err) = strdup ("error allocating memory"); +@@ -1271,10 +1288,24 @@ make_json_map_string_int64 (yajl_val src, const struct parser_context *ctx, pars + { + size_t i; + size_t len = YAJL_GET_OBJECT (src)->len; +- ret = safe_malloc (sizeof(*ret)); ++ char **keys = NULL; ++ int64_t *vals = NULL; ++ ret = smart_calloc (1, 0, sizeof(*ret)); ++ if (ret == NULL) { ++ return NULL; ++ } ++ keys = smart_calloc (len, 1, sizeof (char *)); ++ if (keys == NULL) { ++ return NULL; ++ } ++ vals = smart_calloc (len, 1, sizeof (int64_t)); ++ if (vals == NULL) { ++ free(keys); ++ return NULL; ++ } + ret->len = len; +- ret->keys = safe_malloc ((len + 1) * sizeof (char *)); +- ret->values = safe_malloc ((len + 1) * sizeof (int64_t)); ++ ret->keys = keys; ++ ret->values = vals; + for (i = 0; i < len; i++) + { + const char *srckey = YAJL_GET_OBJECT (src)->keys[i]; +@@ -1320,8 +1351,15 @@ append_json_map_string_int64 (json_map_string_int64 *map, const char *key, int64 + return -1; + + len = map->len + 1; +- keys = safe_malloc (len * sizeof(char *)); +- vals = safe_malloc (len * sizeof(int64_t)); ++ keys = smart_calloc (len, 0, sizeof(char *)); ++ if (keys == NULL) { ++ return -1; ++ } ++ vals = smart_calloc (len, 0, sizeof(int64_t)); ++ if (vals == NULL) { ++ free(keys); ++ return -1; ++ } + + if (map->len) + { +@@ -1411,17 +1449,17 @@ make_json_map_string_bool (yajl_val src, const struct parser_context *ctx, + if (src == NULL || YAJL_GET_OBJECT (src) == NULL) + return NULL; + +- ret = calloc (1, sizeof (*ret)); ++ ret = smart_calloc (1, 0, sizeof (*ret)); + if (ret == NULL) + return NULL; + ret->len = 0; +- ret->keys = calloc (len + 1, sizeof (char *)); ++ ret->keys = smart_calloc (len, 1, sizeof (char *)); + if (ret->keys == NULL) + { + return NULL; + } + +- ret->values = calloc (len + 1, sizeof (bool)); ++ ret->values = smart_calloc (len, 1, sizeof (bool)); + if (ret->values == NULL) + { + return NULL; +@@ -1478,10 +1516,10 @@ append_json_map_string_bool (json_map_string_bool * map, const char *key, + return -1; + + len = map->len + 1; +- keys = calloc (len, sizeof (char *)); ++ keys = smart_calloc (len, 0, sizeof (char *)); + if (keys == NULL) + return -1; +- vals = calloc (len, sizeof (bool)); ++ vals = smart_calloc (len, 0, sizeof (bool)); + if (vals == NULL) + { + return -1; +@@ -1599,14 +1637,14 @@ make_json_map_string_string (yajl_val src, const struct parser_context *ctx, + + ret->len = 0; + +- ret->keys = calloc (len + 1, sizeof (char *)); ++ ret->keys = smart_calloc (len, 1, sizeof (char *)); + if (ret->keys == NULL) + { + *(err) = strdup ("error allocating memory"); + return NULL; + } + +- ret->values = calloc (len + 1, sizeof (char *)); ++ ret->values = smart_calloc (len, 1, sizeof (char *)); + if (ret->values == NULL) + { + *(err) = strdup ("error allocating memory"); +@@ -1731,12 +1769,12 @@ dup_json_map_string_string(const json_map_string_string *src, json_map_string_st + goto out; + } + +- dest->keys = safe_malloc(src->len * sizeof(char *)); ++ dest->keys = smart_calloc(src->len, 0, sizeof(char *)); + if (dest->keys == NULL) { + ret = -1; + goto out; + } +- dest->values = safe_malloc(src->len * sizeof(char *)); ++ dest->values = smart_calloc(src->len, 0, sizeof(char *)); + if (dest->values == NULL) { + free(dest->keys); + dest->keys = NULL; +@@ -1800,7 +1838,7 @@ json_marshal_string (const char *str, size_t length, + return json_buf; + } + +- json_buf = calloc (1, gen_len + 1); ++ json_buf = smart_calloc (gen_len, 1, 1); + if (json_buf == NULL) + { + *err = strdup ("error allocating memory"); +diff --git a/src/third_party/libocispec/common_h.py b/src/third_party/libocispec/common_h.py +index cefe117..af31013 100644 +--- a/src/third_party/libocispec/common_h.py ++++ b/src/third_party/libocispec/common_h.py +@@ -110,6 +110,8 @@ static inline void ptr_free_function(void *p) { + return stat; \\ + } + ++#define JSON_MAX_SIZE (10LL * 1024LL * 1024LL) ++ + typedef char *parser_error; + + struct parser_context +@@ -130,7 +132,7 @@ yajl_val get_val (yajl_val tree, const char *name, yajl_type type); + + char *safe_strdup(const char *src); + +-void *safe_malloc(size_t size); ++void *smart_calloc(size_t count, size_t extra, size_t unit_size); + + int common_safe_double (const char *numstr, double *converted); + +diff --git a/src/third_party/libocispec/sources.py b/src/third_party/libocispec/sources.py +index a85d030..c69cb74 100644 +--- a/src/third_party/libocispec/sources.py ++++ b/src/third_party/libocispec/sources.py +@@ -63,10 +63,10 @@ def parse_map_string_obj(obj, c_file, prefix, obj_typename): + c_file.write(' const char **keys = YAJL_GET_OBJECT_NO_CHECK (tree)->keys;\n') + c_file.write(' yajl_val *values = YAJL_GET_OBJECT_NO_CHECK (tree)->values;\n') + c_file.write(' ret->len = len;\n') +- c_file.write(' ret->keys = calloc (len + 1, sizeof (*ret->keys));\n') ++ c_file.write(' ret->keys = smart_calloc (len, 1, sizeof (*ret->keys));\n') + c_file.write(' if (ret->keys == NULL)\n') + c_file.write(' return NULL;\n') +- c_file.write(' ret->%s = calloc (len + 1, sizeof (*ret->%s));\n' % \ ++ c_file.write(' ret->%s = smart_calloc (len, 1, sizeof (*ret->%s));\n' % \ + (child.fixname, child.fixname)) + c_file.write(' if (ret->%s == NULL)\n' % child.fixname) + c_file.write(' {\n') +@@ -109,14 +109,14 @@ def parse_obj_type_array(obj, c_file, prefix, obj_typename): + c_file.write(' size_t len = YAJL_GET_ARRAY_NO_CHECK (tmp)->len;\n') + c_file.write(' yajl_val *values = YAJL_GET_ARRAY_NO_CHECK (tmp)->values;\n') + c_file.write(' ret->%s_len = len;\n' % (obj.fixname)) +- c_file.write(' ret->%s = calloc (len + 1, sizeof (*ret->%s));\n' % \ ++ c_file.write(' ret->%s = smart_calloc (len, 1, sizeof (*ret->%s));\n' % \ + (obj.fixname, obj.fixname)) + c_file.write(' if (ret->%s == NULL)\n' % obj.fixname) + c_file.write(' {\n') + c_file.write(' return NULL;\n') + c_file.write(' }\n') + if obj.doublearray: +- c_file.write(' ret->%s_item_lens = calloc ( len + 1, sizeof (size_t));\n' ++ c_file.write(' ret->%s_item_lens = smart_calloc ( len, 1, sizeof (size_t));\n' + % (obj.fixname)) + c_file.write(' if (ret->%s_item_lens == NULL)\n' % (obj.fixname)) + c_file.write(' return NULL;\n') +@@ -125,7 +125,7 @@ def parse_obj_type_array(obj, c_file, prefix, obj_typename): + c_file.write(' yajl_val val = values[i];\n') + if obj.doublearray: + c_file.write(' size_t j;\n') +- c_file.write(' ret->%s[i] = calloc ( YAJL_GET_ARRAY_NO_CHECK(val)->len + 1, sizeof (**ret->%s));\n' ++ c_file.write(' ret->%s[i] = smart_calloc ( YAJL_GET_ARRAY_NO_CHECK(val)->len, 1, sizeof (**ret->%s));\n' + % (obj.fixname, obj.fixname)) + c_file.write(' if (ret->%s[i] == NULL)\n' % obj.fixname) + c_file.write(' return NULL;\n') +@@ -158,7 +158,7 @@ def parse_obj_type_array(obj, c_file, prefix, obj_typename): + c_file.write(' {\n') + if obj.doublearray: + c_file.write(' yajl_val *items = YAJL_GET_ARRAY_NO_CHECK(tmp)->values;\n') +- c_file.write(' ret->%s = calloc ( YAJL_GET_ARRAY_NO_CHECK(tmp)->len + 1, sizeof (*ret->%s));\n' ++ c_file.write(' ret->%s = smart_calloc ( YAJL_GET_ARRAY_NO_CHECK(tmp)->len, 1, sizeof (*ret->%s));\n' + % (obj.fixname, obj.fixname)) + c_file.write(' if (ret->%s[i] == NULL)\n' % obj.fixname) + c_file.write(' return NULL;\n') +@@ -194,14 +194,14 @@ def parse_obj_type_array(obj, c_file, prefix, obj_typename): + c_file.write(' size_t len = YAJL_GET_ARRAY_NO_CHECK (tmp)->len;\n') + c_file.write(' yajl_val *values = YAJL_GET_ARRAY_NO_CHECK (tmp)->values;\n') + c_file.write(' ret->%s_len = len;\n' % (obj.fixname)) +- c_file.write(' ret->%s = calloc (len + 1, sizeof (*ret->%s));\n' \ ++ c_file.write(' ret->%s = smart_calloc (len, 1, sizeof (*ret->%s));\n' \ + % (obj.fixname, obj.fixname)) + c_file.write(' if (ret->%s == NULL)\n' % obj.fixname) + c_file.write(' {\n') + c_file.write(' return NULL;\n') + c_file.write(' }\n') + if obj.doublearray: +- c_file.write(' ret->%s_item_lens = calloc ( len + 1, sizeof (size_t));\n' ++ c_file.write(' ret->%s_item_lens = smart_calloc ( len, 1, sizeof (size_t));\n' + % (obj.fixname)) + c_file.write(' if (ret->%s_item_lens == NULL)\n' % (obj.fixname)) + c_file.write(' return NULL;\n') +@@ -209,7 +209,7 @@ def parse_obj_type_array(obj, c_file, prefix, obj_typename): + c_file.write(' {\n') + if obj.doublearray: + c_file.write(' yajl_val *items = YAJL_GET_ARRAY_NO_CHECK(values[i])->values;\n') +- c_file.write(' ret->%s[i] = calloc ( YAJL_GET_ARRAY_NO_CHECK(values[i])->len + 1, sizeof (**ret->%s));\n' ++ c_file.write(' ret->%s[i] = smart_calloc ( YAJL_GET_ARRAY_NO_CHECK(values[i])->len, 1, sizeof (**ret->%s));\n' + % (obj.fixname, obj.fixname)) + c_file.write(' if (ret->%s[i] == NULL)\n' % obj.fixname) + c_file.write(' return NULL;\n') +@@ -344,19 +344,19 @@ def parse_obj_arr_obj(obj, c_file, prefix, obj_typename): + + if (ctx->options & OPT_PARSE_FULLKEY) + { +- resi = calloc (1, sizeof(*tree)); ++ resi = smart_calloc (1, 0, sizeof(*tree)); + if (resi == NULL) + { + return NULL; + } + resi->type = yajl_t_object; +- resi->u.object.keys = calloc (cnt, sizeof (const char *)); ++ resi->u.object.keys = smart_calloc (cnt, 0, sizeof (const char *)); + if (resi->u.object.keys == NULL) + { + yajl_tree_free (resi); + return NULL; + } +- resi->u.object.values = calloc (cnt, sizeof (yajl_val)); ++ resi->u.object.values = smart_calloc (cnt, 0, sizeof (yajl_val)); + if (resi->u.object.values == NULL) + { + yajl_tree_free (resi); +@@ -416,7 +416,7 @@ def parse_json_to_c(obj, c_file, prefix): + c_file.write(" (void) ctx; /* Silence compiler warning. */\n") + c_file.write(" if (tree == NULL)\n") + c_file.write(" return NULL;\n") +- c_file.write(" ret = calloc (1, sizeof (*ret));\n") ++ c_file.write(" ret = smart_calloc (1, 0, sizeof (*ret));\n") + c_file.write(" if (ret == NULL)\n") + c_file.write(" return NULL;\n") + if obj.typ == 'mapStringObject': +@@ -832,7 +832,7 @@ def read_val_generator(c_file, level, src, dest, typ, keyname, obj_typename): + c_file.write('%syajl_val val = %s;\n' % (' ' * (level), src)) + c_file.write('%sif (val != NULL)\n' % (' ' * (level))) + c_file.write('%s {\n' % (' ' * (level))) +- c_file.write('%s%s = calloc (1, sizeof (%s));\n' % ++ c_file.write('%s%s = smart_calloc (1, 0, sizeof (%s));\n' % + (' ' * (level + 1), dest, helpers.get_map_c_types(num_type))) + c_file.write('%sif (%s == NULL)\n' % (' ' * (level + 1), dest)) + c_file.write('%s return NULL;\n' % (' ' * (level + 1))) +@@ -867,7 +867,7 @@ def read_val_generator(c_file, level, src, dest, typ, keyname, obj_typename): + c_file.write('%syajl_val val = %s;\n' % (' ' * (level), src)) + c_file.write('%sif (val != NULL)\n' % (' ' * (level))) + c_file.write('%s {\n' % (' ' * (level))) +- c_file.write('%s%s = calloc (1, sizeof (bool));\n' % (' ' * (level + 1), dest)) ++ c_file.write('%s%s = smart_calloc (1, 0, sizeof (bool));\n' % (' ' * (level + 1), dest)) + c_file.write('%sif (%s == NULL)\n' % (' ' * (level + 1), dest)) + c_file.write('%s return NULL;\n' % (' ' * (level + 1))) + c_file.write('%s*(%s) = YAJL_IS_TRUE(val);\n' % (' ' * (level + 1), dest)) +@@ -878,7 +878,7 @@ def read_val_generator(c_file, level, src, dest, typ, keyname, obj_typename): + % (' ' * (level + 1), keyname)) + c_file.write('%sif (val != NULL)\n' % (' ' * (level + 1))) + c_file.write('%s {\n' % (' ' * (level + 1))) +- c_file.write('%s%s = calloc (1, sizeof (bool));\n' % (' ' * (level + 2), dest)) ++ c_file.write('%s%s = smart_calloc (1, 0, sizeof (bool));\n' % (' ' * (level + 2), dest)) + c_file.write('%sif (%s == NULL)\n' % (' ' * (level + 2), dest)) + c_file.write('%s return NULL;\n' % (' ' * (level + 2))) + c_file.write('%s*(%s) = YAJL_IS_TRUE(val);\n' % (' ' * (level + 2), dest)) +@@ -1163,17 +1163,17 @@ define_cleaner_function (%s *, free_%s)\n + alen = YAJL_GET_ARRAY_NO_CHECK (tree)->len; + if (alen == 0) + return NULL; +- ptr = calloc (1, sizeof (%s)); ++ ptr = smart_calloc (1, 0, sizeof (%s)); + if (ptr == NULL) + return NULL; +- ptr->items = calloc (alen + 1, sizeof(*ptr->items)); ++ ptr->items = smart_calloc (alen, 1, sizeof(*ptr->items)); + if (ptr->items == NULL) + return NULL; + ptr->len = alen; + """ % (typename, typename, typename, typename, typename, typename, typename)) + + if obj.doublearray: +- c_file.write(' ptr->subitem_lens = calloc ( alen + 1, sizeof (size_t));\n') ++ c_file.write(' ptr->subitem_lens = smart_calloc ( alen, 1, sizeof (size_t));\n') + c_file.write(' if (ptr->subitem_lens == NULL)\n') + c_file.write(' return NULL;') + +@@ -1191,7 +1191,7 @@ define_cleaner_function (%s *, free_%s)\n + + if obj.doublearray: + c_file.write(' size_t j;\n') +- c_file.write(' ptr->items[i] = calloc ( YAJL_GET_ARRAY_NO_CHECK(work)->len + 1, sizeof (**ptr->items));\n') ++ c_file.write(' ptr->items[i] = smart_calloc ( YAJL_GET_ARRAY_NO_CHECK(work)->len, 1, sizeof (**ptr->items));\n') + c_file.write(' if (ptr->items[i] == NULL)\n') + c_file.write(' return NULL;\n') + c_file.write(' yajl_val *tmps = YAJL_GET_ARRAY_NO_CHECK(work)->values;\n') +@@ -1220,7 +1220,7 @@ define_cleaner_function (%s *, free_%s)\n + c_file.write(' break;\n') + else: + if obj.doublearray: +- c_file.write(' ptr->items[i] = calloc ( YAJL_GET_ARRAY_NO_CHECK(work)->len + 1, sizeof (**ptr->items));\n') ++ c_file.write(' ptr->items[i] = smart_calloc ( YAJL_GET_ARRAY_NO_CHECK(work)->len, 1, sizeof (**ptr->items));\n') + c_file.write(' if (ptr->items[i] == NULL)\n') + c_file.write(' return NULL;\n') + c_file.write(' size_t j;\n') +@@ -1537,6 +1537,13 @@ define_cleaner_function (yajl_val, yajl_tree_free) + return NULL; + + *err = NULL; ++ if (strlen(jsondata) >= JSON_MAX_SIZE) { ++ if (asprintf(err, "cannot parse the data with length exceeding %%llu", JSON_MAX_SIZE) < 0) { ++ *err = safe_strdup("error allocating memory"); ++ } ++ return NULL; ++ } ++ + if (ctx == NULL) + ctx = (const struct parser_context *)(&tmp_ctx); + +@@ -1601,7 +1608,7 @@ char * + return json_buf; + } + +- json_buf = calloc (1, gen_len + 1); ++ json_buf = smart_calloc (gen_len, 1, 1); + if (json_buf == NULL) + { + *err = strdup ("Cannot allocate memory"); +diff --git a/src/utils/utils_buffer.c b/src/utils/utils_buffer.c +index da34991..05253ad 100644 +--- a/src/utils/utils_buffer.c ++++ b/src/utils/utils_buffer.c +@@ -104,6 +104,10 @@ static int buffer_append(isula_buffer *buf, const char *append, size_t length) + return 0; + } + ++ if (length == SIZE_MAX) { ++ return -1; ++ } ++ + desired_length = length + 1; + if (!buffer_has_space(buf, desired_length)) { + if (buffer_grow(buf, desired_length) != 0) { +diff --git a/src/utils/utils_cgroup.c b/src/utils/utils_cgroup.c +index e4dde72..bd3bc42 100644 +--- a/src/utils/utils_cgroup.c ++++ b/src/utils/utils_cgroup.c +@@ -29,6 +29,11 @@ + /* swap in oci is memoy+swap, so here we need to get real swap */ + int lcr_util_get_real_swap(int64_t memory, int64_t memory_swap, int64_t *swap) + { ++ if (swap == NULL) { ++ ERROR("empty swap pointer"); ++ return -1; ++ } ++ + if (memory == -1 && memory_swap == 0) { + *swap = -1; // -1 is max + return 0; +diff --git a/tests/fuzz/log_fuzz.cc b/tests/fuzz/log_fuzz.cc +index a8f80d4..4128ff6 100644 +--- a/tests/fuzz/log_fuzz.cc ++++ b/tests/fuzz/log_fuzz.cc +@@ -40,7 +40,6 @@ extern "C" void testLog(struct isula_libutils_log_config *conf) + + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) + { +- const char *default_name = "iSula"; + struct isula_libutils_log_config tconf = {0}; + std::string testData(reinterpret_cast(data), size); + std::vector ret_vec; +@@ -67,6 +66,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) + tconf.driver = ret_vec[4].c_str(); + } + } else { ++ const char *default_name = "iSula"; + isula_libutils_default_log_config(default_name, &tconf); + } + +-- +2.34.1 + diff --git a/0008-266-set-env-to-avoid-invoke-lxc-binary-directly.patch b/0008-266-set-env-to-avoid-invoke-lxc-binary-directly.patch new file mode 100644 index 0000000..d7e998f --- /dev/null +++ b/0008-266-set-env-to-avoid-invoke-lxc-binary-directly.patch @@ -0,0 +1,30 @@ +From ac0e25d39dc0eaaf492ea626e1c1bbf3b5f2999f Mon Sep 17 00:00:00 2001 +From: jake +Date: Mon, 18 Sep 2023 11:08:22 +0000 +Subject: [PATCH 8/8] !266 set env to avoid invoke lxc binary directly * set + env to avoid invoke lxc binary directly + +--- + src/runtime/lcrcontainer.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/runtime/lcrcontainer.c b/src/runtime/lcrcontainer.c +index 4270902..ad6dc66 100644 +--- a/src/runtime/lcrcontainer.c ++++ b/src/runtime/lcrcontainer.c +@@ -289,6 +289,12 @@ bool lcr_start(const struct lcr_start_request *request) + close(pipefd[0]); + dup2(pipefd[1], 2); + ++ // should set LXC_MEMFD_REXEC=1 before lxc_start ++ // to improve the security of launching containers ++ if (setenv("LXC_MEMFD_REXEC", "1", true) != 0) { ++ exit(1); ++ } ++ + execute_lxc_start(request->name, path, request); + } + +-- +2.34.1 + diff --git a/lcr.spec b/lcr.spec index 39cddba..b9eb326 100644 --- a/lcr.spec +++ b/lcr.spec @@ -1,5 +1,5 @@ %global _version 2.1.2 -%global _release 2 +%global _release 3 %global _inner_name isula_libutils %global enable_lxc 0 @@ -13,6 +13,15 @@ Group: Applications/System License: LGPLv2.1+ BuildRoot: %{_tmppath}/lcr-%{version} +Patch0001: 0001-support-check-symbols-and-compile-code-in-cmake.patch +Patch0002: 0002-remove-unnecessary-strerror.patch +Patch0003: 0003-improve-code-of-function-in-log.patch +Patch0004: 0004-support-visibility-of-compiler.patch +Patch0005: 0005-refactor-util-buffer-and-add-ut.patch +Patch0006: 0006-264-Support-both-C-11-and-C-17.patch +Patch0007: 0007-262-Fix-empty-pointer-and-overflow.patch +Patch0008: 0008-266-set-env-to-avoid-invoke-lxc-binary-directly.patch + %define lxcver_lower 4.0.3-2022102400 %define lxcver_upper 5.0.3 @@ -85,6 +94,8 @@ install -m 0644 ../build/json/*.h %{buildroot}/%{_includedir}/%{_inner_name}/ install -m 0644 ../src/json/*.h %{buildroot}/%{_includedir}/%{_inner_name}/ install -m 0644 ../src/third_party/*.h %{buildroot}/%{_includedir}/%{_inner_name}/ install -m 0644 ../src/auto_cleanup.h %{buildroot}/%{_includedir}/%{_inner_name}/ +#install header files from utils later +install -m 0644 ../src/utils/utils_compile.h %{buildroot}/%{_includedir}/lcr/utils_compile.h chmod +x %{buildroot}/%{_libdir}/libisula_libutils.so find %{buildroot} -type f -name '*.la' -exec rm -f {} ';' @@ -116,8 +127,15 @@ rm -rf %{buildroot} %defattr(-,root,root,-) %{_includedir}/%{_inner_name}/*.h %{_includedir}/lcr/lcrcontainer.h +%{_includedir}/lcr/utils_compile.h %changelog +* Tue Sep 19 2023 jikai - 2.1.2-3 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:sync from upstream + * Tue Aug 29 2023 xuxuepeng - 2.1.2-2 - Type:bugfix - CVE:NA