From b941ebb1a7f83e92ba8b34d90a583802ddba582f Mon Sep 17 00:00:00 2001 From: BianTanggui Date: Mon, 28 Feb 2022 16:05:37 +0800 Subject: [PATCH] Match-id-8425b352df357b3039764996a692a1fc847f77b7 --- build/scripts/base.list | 4 +- build/scripts/run_main.sh | 1 + cli/src/basic.c | 2 +- cli/src/basic.h | 6 +- cli/src/cgrp.c | 28 +++--- cli/src/logger.c | 26 ++++-- cli/src/options.c | 2 +- cli/src/u_mount.c | 73 ++++++---------- cli/src/utils.c | 100 +++++++++++++++------- cli/src/utils.h | 8 +- install/deb/src/CMakeLists.txt | 2 +- install/deb/src/main.c | 151 +++++++++++++++++++++++++++------ 12 files changed, 267 insertions(+), 136 deletions(-) diff --git a/build/scripts/base.list b/build/scripts/base.list index b66432b..0a6470a 100644 --- a/build/scripts/base.list +++ b/build/scripts/base.list @@ -1,6 +1,4 @@ /usr/local/Ascend/driver/lib64 -/usr/local/Ascend/driver/tools /usr/local/Ascend/driver/include /usr/local/dcmi -/usr/local/bin/npu-smi -/var/log/npu/conf/slog/slog.conf \ No newline at end of file +/usr/local/bin/npu-smi \ No newline at end of file diff --git a/build/scripts/run_main.sh b/build/scripts/run_main.sh index 173bc27..019db12 100644 --- a/build/scripts/run_main.sh +++ b/build/scripts/run_main.sh @@ -53,6 +53,7 @@ function install() fi mv ${SRC} ${DST} + chmod 600 ${DST} echo 'create damom.json success' echo 'please reboot docker daemon to take effect' if [ -f "/var/log/ascend_seclog/ascend_toolbox_install.log" ];then diff --git a/cli/src/basic.c b/cli/src/basic.c index d4de536..e11b50b 100644 --- a/cli/src/basic.c +++ b/cli/src/basic.c @@ -9,7 +9,7 @@ void InitParsedConfig(struct ParsedConfig *parsedConfig) { if (parsedConfig == NULL) { - fprintf(stderr, "parsedConfig pointer is null!\n"); + (void)fprintf(stderr, "parsedConfig pointer is null!\n"); return; } diff --git a/cli/src/basic.h b/cli/src/basic.h index 0dbc67b..f048398 100644 --- a/cli/src/basic.h +++ b/cli/src/basic.h @@ -21,6 +21,8 @@ #define BUF_SIZE 1024 #define MAX_DEVICE_NR 1024 #define MAX_MOUNT_NR 512 + +#define ROOT_UID 0 #define LEVEL_INFO 0 #define LEVEL_WARN 1 @@ -34,9 +36,9 @@ char _content[BUF_SIZE] = {0}; \ int _ret = sprintf_s(_content, BUF_SIZE, fmt, ##__VA_ARGS__); \ if (_ret < 0) { \ - fprintf(stderr, "cannot assemble log content"); \ + (void)fprintf(stderr, "cannot assemble log content"); \ } else { \ - fprintf(stderr, "%s", (const char *)_content); \ + (void)fprintf(stderr, "%s", (const char *)_content); \ } \ } while (0) diff --git a/cli/src/cgrp.c b/cli/src/cgrp.c index d33af23..3f32155 100644 --- a/cli/src/cgrp.c +++ b/cli/src/cgrp.c @@ -22,7 +22,7 @@ bool TakeNthWord(char **pLine, unsigned int n, char **word) { if (pLine == NULL || word == NULL) { - fprintf(stderr, "pLine, word pointer is null!\n"); + (void)fprintf(stderr, "pLine, word pointer is null!\n"); return false; } @@ -41,7 +41,7 @@ bool TakeNthWord(char **pLine, unsigned int n, char **word) bool CheckRootDir(char **pLine) { if (pLine == NULL) { - fprintf(stderr, "pLine pointer is null!\n"); + (void)fprintf(stderr, "pLine pointer is null!\n"); return false; } @@ -56,7 +56,7 @@ bool CheckRootDir(char **pLine) bool CheckFsType(char **pLine) { if (pLine == NULL) { - fprintf(stderr, "pLine pointer is null!\n"); + (void)fprintf(stderr, "pLine pointer is null!\n"); return false; } @@ -71,7 +71,7 @@ bool CheckFsType(char **pLine) bool CheckSubStr(char **pLine, const char *subsys) { if (pLine == NULL || subsys == NULL) { - fprintf(stderr, "pLine, subsys pointer is null!\n"); + (void)fprintf(stderr, "pLine, subsys pointer is null!\n"); return false; } @@ -87,7 +87,7 @@ typedef char *(*ParseFileLine)(char *, const char *); int ParseFileByLine(char* buffer, int bufferSize, const ParseFileLine fn, const char* filepath) { if (buffer == NULL || filepath == NULL) { - fprintf(stderr, "buffer, filepath pointer is null!\n"); + (void)fprintf(stderr, "buffer, filepath pointer is null!\n"); return -1; } @@ -101,7 +101,8 @@ int ParseFileByLine(char* buffer, int bufferSize, const ParseFileLine fn, const Logger("Cannot canonicalize path.", LEVEL_ERROR, SCREEN_YES); return -1; } - if (CheckLegality(resolvedPath) != 0) { + const size_t maxFileSzieMb = 1024; // max 1G + if (!CheckExternalFile(resolvedPath, strlen(resolvedPath), maxFileSzieMb, true)) { Logger("Check file legality failed.", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -131,7 +132,7 @@ int ParseFileByLine(char* buffer, int bufferSize, const ParseFileLine fn, const char *GetCgroupMount(char *line, const char *subsys) { if (line == NULL || subsys == NULL) { - fprintf(stderr, "line, subsys pointer is null!\n"); + (void)fprintf(stderr, "line, subsys pointer is null!\n"); return NULL; } @@ -160,7 +161,7 @@ char *GetCgroupMount(char *line, const char *subsys) char *GetCgroupRoot(char *line, const char *subSystem) { if (line == NULL || subSystem == NULL) { - fprintf(stderr, "line, subSystem pointer is null!\n"); + (void)fprintf(stderr, "line, subSystem pointer is null!\n"); return NULL; } @@ -190,7 +191,7 @@ char *GetCgroupRoot(char *line, const char *subSystem) int SetupDeviceCgroup(FILE *cgroupAllow, const char *devName) { if (cgroupAllow == NULL || devName == NULL) { - fprintf(stderr, "cgroupAllow, devName pointer is null!\n"); + (void)fprintf(stderr, "cgroupAllow, devName pointer is null!\n"); return -1; } @@ -225,7 +226,7 @@ int SetupDeviceCgroup(FILE *cgroupAllow, const char *devName) int SetupDriverCgroup(FILE *cgroupAllow) { if (cgroupAllow == NULL) { - fprintf(stderr, "cgroupAllow pointer is null!\n"); + (void)fprintf(stderr, "cgroupAllow pointer is null!\n"); return -1; } @@ -260,7 +261,7 @@ int SetupDriverCgroup(FILE *cgroupAllow) int GetCgroupPath(int pid, char *effPath, size_t maxSize) { if (effPath == NULL) { - fprintf(stderr, "effPath pointer is null!\n"); + (void)fprintf(stderr, "effPath pointer is null!\n"); return -1; } @@ -313,7 +314,7 @@ int GetCgroupPath(int pid, char *effPath, size_t maxSize) int SetupCgroup(const struct ParsedConfig *config) { if (config == NULL) { - fprintf(stderr, "config pointer is null!\n"); + (void)fprintf(stderr, "config pointer is null!\n"); return -1; } @@ -325,7 +326,8 @@ int SetupCgroup(const struct ParsedConfig *config) Logger("cannot canonicalize cgroup.", LEVEL_ERROR, SCREEN_YES); return -1; } - if (CheckLegality(resolvedCgroupPath) != 0) { + const size_t maxFileSzieMb = 1024; // max 1G + if (!CheckExternalFile(resolvedCgroupPath, strlen(resolvedCgroupPath), maxFileSzieMb, true)) { Logger("Check file legality failed.", LEVEL_ERROR, SCREEN_YES); return -1; } diff --git a/cli/src/logger.c b/cli/src/logger.c index 4445c78..7958c7b 100644 --- a/cli/src/logger.c +++ b/cli/src/logger.c @@ -23,7 +23,7 @@ int GetCurrentLocalTime(char* buffer, int length) { if (buffer == NULL) { - fprintf(stderr, "buffer pointer is null!\n"); + (void)fprintf(stderr, "buffer pointer is null!\n"); return -1; } @@ -62,7 +62,7 @@ int CreateLog(const char* filename) long GetLogSize(const char* filename) { if (filename == NULL) { - fprintf(stderr, "filename pointer is null!\n"); + (void)fprintf(stderr, "filename pointer is null!\n"); return -1; } @@ -73,11 +73,15 @@ long GetLogSize(const char* filename) } FILE *fp = NULL; char path[PATH_MAX + 1] = {0x00}; - if (strlen(filename) > PATH_MAX || NULL == realpath(filename, path)) { + if (strlen(filename) > PATH_MAX || realpath(filename, path) == NULL) { return -1; } - if (CheckLegality(path) != 0) { - return -1; + struct stat fileStat; + if ((stat(path, &fileStat) == 0) && (S_ISREG(fileStat.st_mode) != 0)) { + const size_t maxFileSzieMb = 50; // max 50MB + if (!CheckExternalFile(path, strlen(path), maxFileSzieMb, true)) { + return -1; + } } fp = fopen(path, "rb"); long length = 0; @@ -96,7 +100,7 @@ long GetLogSize(const char* filename) int LogLoop(const char* filename) { if (filename == NULL) { - fprintf(stderr, "filename pointer is null!\n"); + (void)fprintf(stderr, "filename pointer is null!\n"); return -1; } @@ -121,7 +125,7 @@ int LogLoop(const char* filename) void WriteLogFile(const char* filename, long maxSize, const char* buffer, unsigned bufferSize) { if (filename == NULL || buffer == NULL) { - fprintf(stderr, "filename, buffer pointer is null!\n"); + (void)fprintf(stderr, "filename, buffer pointer is null!\n"); return; } @@ -142,8 +146,12 @@ void WriteLogFile(const char* filename, long maxSize, const char* buffer, unsign if (strlen(filename) > PATH_MAX || NULL == realpath(filename, path)) { return; } - if (CheckLegality(path) != 0) { - return; + struct stat fileStat; + if ((stat(path, &fileStat) == 0) && (S_ISREG(fileStat.st_mode) != 0)) { + const size_t maxFileSzieMb = 50; // max 50MB + if (!CheckExternalFile(path, strlen(path), maxFileSzieMb, true)) { + return; + } } fp = fopen(path, "a+"); if (fp != NULL) { diff --git a/cli/src/options.c b/cli/src/options.c index 2300016..f5c546f 100644 --- a/cli/src/options.c +++ b/cli/src/options.c @@ -25,7 +25,7 @@ static struct { void ParseRuntimeOptions(const char *options) { if (options == NULL) { - fprintf(stderr, "options pointer is null!\n"); + (void)fprintf(stderr, "options pointer is null!\n"); return; } diff --git a/cli/src/u_mount.c b/cli/src/u_mount.c index d6ed4ac..090ca85 100644 --- a/cli/src/u_mount.c +++ b/cli/src/u_mount.c @@ -26,20 +26,27 @@ int Mount(const char *src, const char *dst) static const unsigned long mountFlags = MS_BIND; static const unsigned long remountFlags = MS_BIND | MS_REMOUNT | MS_RDONLY | MS_NOSUID; int ret; - + struct stat fileStat; + if ((stat(src, &fileStat) == 0) && + ((S_ISREG(fileStat.st_mode) != 0) || (S_ISDIR(fileStat.st_mode) != 0))) { // 只校验文件和目录 + const size_t maxFileSzieMb = 10 * 1024; // max 10 G + if (!CheckExternalFile(src, strlen(src), maxFileSzieMb, false)) { + char* str = FormatLogMessage("failed to mount src hehe:%s.", src); + Logger(str, LEVEL_ERROR, SCREEN_YES); + free(str); + Logger("failed to Check src.", LEVEL_ERROR, SCREEN_YES); + return -1; + } + } ret = mount(src, dst, NULL, mountFlags, NULL); if (ret < 0) { - char* str = FormatLogMessage("failed to mount src:%s.", src); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to mount src.", LEVEL_ERROR, SCREEN_YES); return -1; } ret = mount(NULL, dst, NULL, remountFlags, NULL); if (ret < 0) { - char* str = FormatLogMessage("failed to re-mount. dst:%s.", dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to re-mount. dst.", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -80,9 +87,7 @@ static int GetDeviceMntSrcDst(const char *rootfs, const char *srcDeviceName, } if (realpath(unresolvedDst, resolvedDst) == NULL && errno != ENOENT) { - char* str = FormatLogMessage("cannot canonicalize device dst: %s.", dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("cannot canonicalize device dst.", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -94,9 +99,7 @@ static int GetDeviceMntSrcDst(const char *rootfs, const char *srcDeviceName, } else { err = strcpy_s(dst, dstBufSize, resolvedDst); if (err != EOK) { - char* str = FormatLogMessage("failed to copy resolved device mnt path to dst: %s.", resolvedDst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to copy resolved device mnt path to dst.", LEVEL_ERROR, SCREEN_YES); return -1; } } @@ -113,18 +116,14 @@ int MountDevice(const char *rootfs, const char *srcDeviceName, const char *dstDe struct PathInfo pathInfo = {src, BUF_SIZE, dst, BUF_SIZE}; ret = GetDeviceMntSrcDst(rootfs, srcDeviceName, dstDeviceName, &pathInfo); if (ret < 0) { - str = FormatLogMessage("failed to get mount src and dst path, device name: %s.", srcDeviceName); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to get mount src and dst path.", LEVEL_ERROR, SCREEN_YES); return -1; } struct stat srcStat; ret = stat((const char *)src, &srcStat); if (ret < 0) { - str = FormatLogMessage("failed to stat src: %s.", src); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to stat src.", LEVEL_ERROR, SCREEN_YES); return -1; } errno = 0; @@ -133,9 +132,7 @@ int MountDevice(const char *rootfs, const char *srcDeviceName, const char *dstDe if (ret == 0 && S_ISCHR(dstStat.st_mode)) { return 0; // 特权容器自动挂载HOST所有设备,故此处跳过 } else if (ret == 0) { - str = FormatLogMessage("%s already exists but not a char device as expected.", dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("dst already exists but not a char device as expected.", LEVEL_ERROR, SCREEN_YES); return -1; } else if (ret < 0 && errno != ENOENT) { Logger("failed to check dst stat", LEVEL_ERROR, SCREEN_YES); @@ -143,9 +140,7 @@ int MountDevice(const char *rootfs, const char *srcDeviceName, const char *dstDe } ret = MakeMountPoints(dst, srcStat.st_mode); if (ret < 0) { - str = FormatLogMessage("failed to create mount dst file: %s.", dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to create mount dst file.", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -179,9 +174,7 @@ int DoDeviceMounting(const char *rootfs, const char *device_name, const unsigned } int ret = MountDevice(rootfs, srcDeviceName, dstDeviceName); if (ret < 0) { - char* str = FormatLogMessage("failed to mount device %s.", srcDeviceName); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to mount device.", LEVEL_ERROR, SCREEN_YES); return -1; } } @@ -201,9 +194,7 @@ int MountFile(const char *rootfs, const char *filepath) ret = sprintf_s(dst, BUF_SIZE, "%s%s", rootfs, filepath); if (ret < 0) { - char* str = FormatLogMessage("failed to assemble file mounting path, file: %s.", filepath); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to assemble file mounting path.", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -215,9 +206,7 @@ int MountFile(const char *rootfs, const char *filepath) ret = MakeMountPoints(dst, srcStat.st_mode); if (ret < 0) { - char* str = FormatLogMessage("failed to create mount dst file: %s.", dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to create mount dst file.", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -253,17 +242,13 @@ int MountDir(const char *rootfs, const char *src) ret = MakeDirWithParent(dst, DEFAULT_DIR_MODE); if (ret < 0) { - char* str = FormatLogMessage("failed to make dir: %s.", dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to make dir.", LEVEL_ERROR, SCREEN_YES); return -1; } ret = Mount(src, dst); if (ret < 0) { - char* str = FormatLogMessage("failed to mount dir: %s to %s.", src, dst); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to mount dir", LEVEL_ERROR, SCREEN_YES); return -1; } @@ -316,9 +301,7 @@ int DoDirectoryMounting(const char *rootfs, const struct MountList *list) for (unsigned int i = 0; i < list->count; i++) { ret = MountDir(rootfs, (const char *)&list->list[i][0]); if (ret < 0) { - char* str = FormatLogMessage("failed to do directory mounting for %s.", (const char *)&list->list[i][0]); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to do directory mounting", LEVEL_ERROR, SCREEN_YES); return -1; } } @@ -337,9 +320,7 @@ int DoFileMounting(const char *rootfs, const struct MountList *list) for (unsigned int i = 0; i < list->count; i++) { ret = MountFile(rootfs, (const char *)&list->list[i][0]); if (ret < 0) { - char* str = FormatLogMessage("failed to do file mounting for %s.", (const char *)&list->list[i][0]); - Logger(str, LEVEL_ERROR, SCREEN_YES); - free(str); + Logger("failed to do file mounting for.", LEVEL_ERROR, SCREEN_YES); return -1; } } diff --git a/cli/src/utils.c b/cli/src/utils.c index 44c89ba..8cb8a1d 100644 --- a/cli/src/utils.c +++ b/cli/src/utils.c @@ -13,13 +13,14 @@ #include #include #include + #include "securec.h" #include "logger.h" char *FormatLogMessage(char *format, ...) { if (format == NULL) { - fprintf(stderr, "format pointer is null!\n"); + (void)fprintf(stderr, "format pointer is null!\n"); return NULL; } @@ -61,7 +62,7 @@ int StrHasPrefix(const char *str, const char *prefix) int MkDir(const char *dir, int mode) { if (dir == NULL) { - fprintf(stderr, "dir pointer is null!\n"); + (void)fprintf(stderr, "dir pointer is null!\n"); return -1; } @@ -79,7 +80,7 @@ int VerifyPathInfo(const struct PathInfo* pathInfo) int CheckDirExists(const char *dir) { if (dir == NULL) { - fprintf(stderr, "dir pointer is null!\n"); + (void)fprintf(stderr, "dir pointer is null!\n"); return -1; } @@ -95,7 +96,7 @@ int CheckDirExists(const char *dir) int GetParentPathStr(const char *path, char *parent, size_t bufSize) { if (path == NULL || parent == NULL) { - fprintf(stderr, "path pointer or parentPath is null!\n"); + (void)fprintf(stderr, "path pointer or parentPath is null!\n"); return -1; } @@ -120,7 +121,7 @@ int GetParentPathStr(const char *path, char *parent, size_t bufSize) int MakeDirWithParent(const char *path, mode_t mode) { if (path == NULL) { - fprintf(stderr, "path pointer is null!\n"); + (void)fprintf(stderr, "path pointer is null!\n"); return -1; } @@ -148,7 +149,7 @@ int MakeDirWithParent(const char *path, mode_t mode) int MakeMountPoints(const char *path, mode_t mode) { if (path == NULL) { - fprintf(stderr, "path pointer is null!\n"); + (void)fprintf(stderr, "path pointer is null!\n"); return -1; } @@ -177,32 +178,73 @@ int MakeMountPoints(const char *path, mode_t mode) return 0; } -int CheckLegality(const char* filename) +static bool ShowExceptionInfo(const char* exceptionInfo) { - if (filename == NULL) { - fprintf(stderr, "filename pointer is null!\n"); - return -1; + (void)fprintf(stderr, exceptionInfo); + (void)fprintf(stderr, "\n"); + return false; +} + +static bool CheckLegality(const char* resolvedPath, const size_t resolvedPathLen, + const unsigned long long maxFileSzieMb, const bool checkOwner) +{ + const unsigned long long maxFileSzieB = maxFileSzieMb * 1024 * 1024; + char buf[PATH_MAX] = {0}; + if (strncpy_s(buf, sizeof(buf), resolvedPath, resolvedPathLen) != EOK) { + return false; } - - char buf[PATH_MAX + 1] = {0x00}; - errno_t ret = strncpy_s(buf, PATH_MAX + 1, filename, strlen(filename)); - if (ret != EOK) { - return -1; + struct stat fileStat; + if ((stat(buf, &fileStat) != 0) || + ((S_ISREG(fileStat.st_mode) == 0) && (S_ISDIR(fileStat.st_mode) == 0))) { + return ShowExceptionInfo("resolvedPath does not exist or is not a file!"); } - do { - struct stat fileStat; - if (stat(buf, &fileStat) != 0) { - return -1; - } - if ((fileStat.st_uid != ROOT_UID) && (fileStat.st_uid != geteuid())) { // 操作文件owner非root/自己 - fprintf(stderr, "Please check the folder owner!\n"); - return -1; + if (fileStat.st_size >= maxFileSzieB) { // 文件大小超限 + return ShowExceptionInfo("fileSize out of bounds!"); + } + for (int iLoop = 0; iLoop < PATH_MAX; iLoop++) { + if (checkOwner) { + if ((fileStat.st_uid != ROOT_UID) && (fileStat.st_uid != geteuid())) { // 操作文件owner非root/自己 + return ShowExceptionInfo("Please check the folder owner!"); + } } if ((fileStat.st_mode & S_IWOTH) != 0) { // 操作文件对other用户可写 - fprintf(stderr, "Please check the write permission!\n"); - return -1; + return ShowExceptionInfo("Please check the write permission!"); } - } while (strncmp(dirname(buf), "/", strlen(dirname(buf)))); - - return 0; -} \ No newline at end of file + if ((strcmp(buf, "/") == 0) || (strstr(buf, "/") == NULL)) { + break; + } + if (strcmp(dirname(buf), ".") == 0) { + break; + } + if (stat(buf, &fileStat) != 0) { + return false; + } + } + return true; +} + +bool CheckExternalFile(const char* filePath, const size_t filePathLen, + const size_t maxFileSzieMb, const bool checkOwner) +{ + int iLoop; + if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界 + return ShowExceptionInfo("filePathLen out of bounds!"); + } + if (strstr(filePath, "..") != NULL) { // 存在".." + return ShowExceptionInfo("filePath has an illegal character!"); + } + for (iLoop = 0; iLoop < filePathLen; iLoop++) { + if ((isalnum(filePath[iLoop]) == 0) && (filePath[iLoop] != '.') && (filePath[iLoop] != '_') && + (filePath[iLoop] != '-') && (filePath[iLoop] != '/') && (filePath[iLoop] != '~')) { // 非法字符 + return ShowExceptionInfo("filePath has an illegal character!"); + } + } + char resolvedPath[PATH_MAX] = {0}; + if (realpath(filePath, resolvedPath) == NULL && errno != ENOENT) { + return ShowExceptionInfo("realpath failed!"); + } + if (strstr(resolvedPath, filePath) == NULL) { // 存在软链接 + return ShowExceptionInfo("filePath has a soft link!"); + } + return CheckLegality(resolvedPath, strlen(resolvedPath), maxFileSzieMb, checkOwner); +} diff --git a/cli/src/utils.h b/cli/src/utils.h index ab83b5f..7c803ca 100644 --- a/cli/src/utils.h +++ b/cli/src/utils.h @@ -8,10 +8,11 @@ #include #include #include +#include +#include +#include #include "basic.h" -#define ROOT_UID 0 - char *FormatLogMessage(char *format, ...); int IsStrEqual(const char *s1, const char *s2); int StrHasPrefix(const char *str, const char *prefix); @@ -21,6 +22,7 @@ int CheckDirExists(const char *dir); int GetParentPathStr(const char *path, char *parent, size_t bufSize); int MakeDirWithParent(const char *path, mode_t mode); int MakeMountPoints(const char *path, mode_t mode); -int CheckLegality(const char* filename); +bool CheckExternalFile(const char* filePath, const size_t filePathLen, + const size_t maxFileSzieMb, const bool checkOwner); #endif \ No newline at end of file diff --git a/install/deb/src/CMakeLists.txt b/install/deb/src/CMakeLists.txt index e0db884..38d47cb 100644 --- a/install/deb/src/CMakeLists.txt +++ b/install/deb/src/CMakeLists.txt @@ -24,7 +24,7 @@ add_executable(ascend-docker-plugin-install-helper ${SRC}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../build/cjson ${CMAKE_CURRENT_SOURCE_DIR}/../../../build/cjson) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../build/HuaweiSecureC ${CMAKE_CURRENT_SOURCE_DIR}/../../../build/HuaweiSecureC) -# 添加链接库 +# 添加链接库 #该命令要在add_executable命令下方,否则报错 target_compile_options(ascend-docker-plugin-install-helper PRIVATE -fstack-protector-all -fpie) target_link_libraries(ascend-docker-plugin-install-helper -pie -Wl,-s,-z,now cjson) diff --git a/install/deb/src/main.c b/install/deb/src/main.c index 2be6344..7a703fd 100644 --- a/install/deb/src/main.c +++ b/install/deb/src/main.c @@ -6,7 +6,13 @@ #include #include #include +#include +#include +#include +#include +#include #include "cJSON.h" +#include "securec.h" #define MAX_JSON_FILE_SIZE 65535 #define MIN_ARGS_NUM 4 @@ -27,7 +33,7 @@ static void ReadJsonFile(FILE *pf, char *text, int maxBufferSize) { if (pf == NULL || text == NULL) { - fprintf(stderr, "file pointer or text pointer are null!\n"); + (void)fprintf(stderr, "file pointer or text pointer are null!\n"); return; } @@ -35,7 +41,7 @@ static void ReadJsonFile(FILE *pf, char *text, int maxBufferSize) int size = (int)ftell(pf); if (size >= maxBufferSize) { - fprintf(stderr, "file size too large\n"); + (void)fprintf(stderr, "file size too large\n"); return; } @@ -49,21 +55,21 @@ static void ReadJsonFile(FILE *pf, char *text, int maxBufferSize) static cJSON *CreateAscendRuntimeInfo(const char *runtimePath) { if (runtimePath == NULL) { - fprintf(stderr, "runtimePath pointer are null!\n"); + (void)fprintf(stderr, "runtimePath pointer are null!\n"); return NULL; } cJSON *root = NULL; root = cJSON_CreateObject(); if (root == NULL) { - fprintf(stderr, "create ascend runtime info root err\n"); + (void)fprintf(stderr, "create ascend runtime info root err\n"); return NULL; } cJSON *newString = NULL; newString = cJSON_CreateString(runtimePath); if (newString == NULL) { - fprintf(stderr, "create ascend runtime info path value err\n"); + (void)fprintf(stderr, "create ascend runtime info path value err\n"); cJSON_Delete(root); return NULL; } @@ -71,7 +77,7 @@ static cJSON *CreateAscendRuntimeInfo(const char *runtimePath) cJSON *paraArray = NULL; paraArray = cJSON_CreateArray(); if (paraArray == NULL) { - fprintf(stderr, "create ascend runtime info args err\n"); + (void)fprintf(stderr, "create ascend runtime info args err\n"); cJSON_Delete(root); cJSON_Delete(newString); return NULL; @@ -86,21 +92,21 @@ static cJSON *CreateAscendRuntimeInfo(const char *runtimePath) static cJSON *CreateRuntimes(const char *runtimePath) { if (runtimePath == NULL) { - fprintf(stderr, "runtimePath pointer is null!\n"); + (void)fprintf(stderr, "runtimePath pointer is null!\n"); return NULL; } cJSON *ascendRuntime = NULL; ascendRuntime = CreateAscendRuntimeInfo(runtimePath); if (ascendRuntime == NULL) { - fprintf(stderr, "create ascendruntime err\n"); + (void)fprintf(stderr, "create ascendruntime err\n"); return NULL; } cJSON *runtimes = NULL; runtimes = cJSON_CreateObject(); if (runtimes == NULL) { - fprintf(stderr, "create runtimes err\n"); + (void)fprintf(stderr, "create runtimes err\n"); cJSON_Delete(ascendRuntime); return NULL; } @@ -113,7 +119,7 @@ static cJSON *CreateRuntimes(const char *runtimePath) static int DelJsonContent(cJSON *root, const char *key) { if (root == NULL || key == NULL) { - fprintf(stderr, "userInfo pointer is null!\n"); + (void)fprintf(stderr, "userInfo pointer is null!\n"); return -1; } @@ -126,7 +132,7 @@ static int DelJsonContent(cJSON *root, const char *key) cJSON *removedItem = NULL; removedItem = cJSON_DetachItemViaPointer(root, existItem); if (removedItem == NULL) { - fprintf(stderr, "remove %s failed\n", key); + (void)fprintf(stderr, "remove %s failed\n", key); free(existItem); existItem = NULL; return -1; @@ -139,7 +145,7 @@ static int DelJsonContent(cJSON *root, const char *key) static cJSON *CreateContent(const char *runtimePath) { if (runtimePath == NULL) { - fprintf(stderr, "runtimePath pointer is null!\n"); + (void)fprintf(stderr, "runtimePath pointer is null!\n"); return NULL; } @@ -147,7 +153,7 @@ static cJSON *CreateContent(const char *runtimePath) cJSON *runtimes = NULL; runtimes = CreateRuntimes(runtimePath); if (runtimes == NULL) { - fprintf(stderr, "create runtimes err\n"); + (void)fprintf(stderr, "create runtimes err\n"); return NULL; } @@ -162,7 +168,7 @@ static cJSON *CreateContent(const char *runtimePath) root = cJSON_CreateObject(); if (root == NULL) { /* ascendRuntime已经挂载到runtimes上了,再释放会coredump */ - fprintf(stderr, "create root err\n"); + (void)fprintf(stderr, "create root err\n"); cJSON_Delete(runtimes); cJSON_Delete(defaultRuntime); return NULL; @@ -178,7 +184,7 @@ static cJSON *CreateContent(const char *runtimePath) static cJSON *ModifyContent(FILE *pf, const char *runtimePath) { if (pf == NULL || runtimePath == NULL) { - fprintf(stderr, "file pointer or runtimePath pointer is null!\n"); + (void)fprintf(stderr, "file pointer or runtimePath pointer is null!\n"); return NULL; } @@ -188,7 +194,7 @@ static cJSON *ModifyContent(FILE *pf, const char *runtimePath) cJSON *root = NULL; root = cJSON_Parse(jsonStr); if (root == NULL) { - fprintf(stderr, "Error before: [%s]\n", cJSON_GetErrorPtr()); + (void)fprintf(stderr, "Error before: [%s]\n", cJSON_GetErrorPtr()); return NULL; } @@ -236,7 +242,7 @@ static cJSON *ModifyContent(FILE *pf, const char *runtimePath) static cJSON *RemoveContent(FILE *pf) { if (pf == NULL) { - fprintf(stderr, "file pointer is null!\n"); + (void)fprintf(stderr, "file pointer is null!\n"); return NULL; } @@ -246,7 +252,7 @@ static cJSON *RemoveContent(FILE *pf) cJSON *root = NULL; root = cJSON_Parse(jsonStr); if (root == NULL) { - fprintf(stderr, "Error before: [%s]\n", cJSON_GetErrorPtr()); + (void)fprintf(stderr, "Error before: [%s]\n", cJSON_GetErrorPtr()); return NULL; } @@ -261,7 +267,7 @@ static cJSON *RemoveContent(FILE *pf) cJSON *runtimes = NULL; runtimes = cJSON_GetObjectItem(root, RUNTIME_KEY); if (runtimes == NULL) { - fprintf(stderr, "no runtime key found\n"); + (void)fprintf(stderr, "no runtime key found\n"); cJSON_Delete(root); return NULL; } @@ -275,14 +281,99 @@ static cJSON *RemoveContent(FILE *pf) return root; } +static bool ShowExceptionInfo(const char* exceptionInfo) +{ + (void)fprintf(stderr, exceptionInfo); + (void)fprintf(stderr, "\n"); + return false; +} + +static bool CheckLegality(const char* resolvedPath, const size_t resolvedPathLen, + const unsigned long long maxFileSzieMb, const bool checkOwner) +{ + const unsigned long long maxFileSzieB = maxFileSzieMb * 1024 * 1024; + char buf[PATH_MAX] = {0}; + if (strncpy_s(buf, sizeof(buf), resolvedPath, resolvedPathLen) != EOK) { + return false; + } + struct stat fileStat; + if ((stat(buf, &fileStat) != 0) || + ((S_ISREG(fileStat.st_mode) == 0) && (S_ISDIR(fileStat.st_mode) == 0))) { + return ShowExceptionInfo("resolvedPath does not exist or is not a file!"); + } + if (fileStat.st_size >= maxFileSzieB) { // 文件大小超限 + return ShowExceptionInfo("fileSize out of bounds!"); + } + for (int iLoop = 0; iLoop < PATH_MAX; iLoop++) { + if (checkOwner) { + if ((fileStat.st_uid != 0) && (fileStat.st_uid != geteuid())) { // 操作文件owner非root/自己 + return ShowExceptionInfo("Please check the folder owner!"); + } + } + if ((fileStat.st_mode & S_IWOTH) != 0) { // 操作文件对other用户可写 + return ShowExceptionInfo("Please check the write permission!"); + } + if ((strcmp(buf, "/") == 0) || (strstr(buf, "/") == NULL)) { + break; + } + if (strcmp(dirname(buf), ".") == 0) { + break; + } + if (stat(buf, &fileStat) != 0) { + return false; + } + } + return true; +} + +static bool CheckExternalFile(const char* filePath, const size_t filePathLen, + const size_t maxFileSzieMb, const bool checkOwner) +{ + int iLoop; + if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界 + return ShowExceptionInfo("filePathLen out of bounds!"); + } + if (strstr(filePath, "..") != NULL) { // 存在".." + return ShowExceptionInfo("filePath has an illegal character!"); + } + for (iLoop = 0; iLoop < filePathLen; iLoop++) { + if ((isalnum(filePath[iLoop]) == 0) && (filePath[iLoop] != '.') && (filePath[iLoop] != '_') && + (filePath[iLoop] != '-') && (filePath[iLoop] != '/') && (filePath[iLoop] != '~')) { // 非法字符 + return ShowExceptionInfo("filePath has an illegal character!"); + } + } + char resolvedPath[PATH_MAX] = {0}; + if (realpath(filePath, resolvedPath) == NULL && errno != ENOENT) { + return ShowExceptionInfo("realpath failed!"); + } + return CheckLegality(resolvedPath, strlen(resolvedPath), maxFileSzieMb, checkOwner); +} + +static bool CheckJsonFile(const char *jsonFilePath, const size_t jsonFilePathLen) +{ + struct stat fileStat; + if ((stat(jsonFilePath, &fileStat) == 0) && (S_ISREG(fileStat.st_mode) != 0)) { + const size_t maxFileSzieMb = 10; // max 10MB + if (!CheckExternalFile(jsonFilePath, jsonFilePathLen, maxFileSzieMb, true)) { + return false; + } + } + return true; +} static int DetectAndCreateJsonFile(const char *filePath, const char *tempPath, const char *runtimePath) { if (filePath == NULL || tempPath == NULL || runtimePath == NULL) { - fprintf(stderr, "filePath, tempPath or runtimePath are null!\n"); + (void)fprintf(stderr, "filePath, tempPath or runtimePath are null!\n"); return -1; } + if (!CheckJsonFile(filePath, strlen(filePath)) || !CheckJsonFile(tempPath, strlen(tempPath)) || + !CheckJsonFile(runtimePath, strlen(runtimePath))) { + (void)fprintf(stderr, "filePath, tempPath or runtimePath check failed!\n"); + return -1; + } + cJSON *root = NULL; FILE *pf = NULL; pf = fopen(filePath, "r+"); @@ -294,18 +385,18 @@ static int DetectAndCreateJsonFile(const char *filePath, const char *tempPath, c } if (root == NULL) { - fprintf(stderr, "error: failed to create json\n"); + (void)fprintf(stderr, "error: failed to create json\n"); return -1; } pf = fopen(tempPath, "w"); if (pf == NULL) { - fprintf(stderr, "error: failed to create file\n"); + (void)fprintf(stderr, "error: failed to create file\n"); return -1; } if (fprintf(pf, "%s", cJSON_Print(root)) < 0) { - fprintf(stderr, "error: failed to create file\n"); + (void)fprintf(stderr, "error: failed to create file\n"); (void)fclose(pf); cJSON_Delete(root); return -1; @@ -320,14 +411,18 @@ static int DetectAndCreateJsonFile(const char *filePath, const char *tempPath, c static int CreateRevisedJsonFile(const char *filePath, const char *tempPath) { if (filePath == NULL || tempPath == NULL) { - fprintf(stderr, "filePath or tempPath are null!\n"); + (void)fprintf(stderr, "filePath or tempPath are null!\n"); + return -1; + } + if (!CheckJsonFile(filePath, strlen(filePath)) || !CheckJsonFile(tempPath, strlen(tempPath))) { + (void)fprintf(stderr, "filePath, tempPath check failed!\n"); return -1; } FILE *pf = NULL; pf = fopen(filePath, "r+"); if (pf == NULL) { - fprintf(stderr, "error: no json files found\n"); + (void)fprintf(stderr, "error: no json files found\n"); return -1; } cJSON *newContent = NULL; @@ -335,7 +430,7 @@ static int CreateRevisedJsonFile(const char *filePath, const char *tempPath) (void)fclose(pf); if (newContent == NULL) { - fprintf(stderr, "error: failed to create json\n"); + (void)fprintf(stderr, "error: failed to create json\n"); if (pf != NULL) { (void)fclose(pf); pf = NULL; @@ -345,13 +440,13 @@ static int CreateRevisedJsonFile(const char *filePath, const char *tempPath) pf = fopen(tempPath, "w"); if (pf == NULL) { - fprintf(stderr, "error: failed to create file\n"); + (void)fprintf(stderr, "error: failed to create file\n"); cJSON_Delete(newContent); return -1; } if (fprintf(pf, "%s", cJSON_Print(newContent)) < 0) { - fprintf(stderr, "error: failed to create file\n"); + (void)fprintf(stderr, "error: failed to create file\n"); cJSON_Delete(newContent); if (pf != NULL) { (void)fclose(pf);