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 a9ae06e..e04ec24 100644 --- a/build/scripts/run_main.sh +++ b/build/scripts/run_main.sh @@ -52,7 +52,8 @@ function install() exit 1 fi - mv ${SRC} ${DST} + 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..47bf0f2 100644 --- a/cli/src/basic.h +++ b/cli/src/basic.h @@ -22,6 +22,8 @@ #define MAX_DEVICE_NR 1024 #define MAX_MOUNT_NR 512 +#define ROOT_UID 0 + #define LEVEL_INFO 0 #define LEVEL_WARN 1 #define LEVEL_ERROR 2 @@ -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..3871c07 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; } @@ -139,11 +143,15 @@ void WriteLogFile(const char* filename, long maxSize, const char* buffer, unsign return; } } - if (strlen(filename) > PATH_MAX || NULL == realpath(filename, path)) { + if (strlen(filename) > PATH_MAX || realpath(filename, path) == NULL) { 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 76b9e67..31ba172 100644 --- a/cli/src/u_mount.c +++ b/cli/src/u_mount.c @@ -26,20 +26,25 @@ 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); + 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 +85,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 +97,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 +114,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 +130,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 +138,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 +172,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 +192,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 +204,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 +240,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 +299,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; } } diff --git a/cli/src/utils.c b/cli/src/utils.c index bacfd88..29fedff 100644 --- a/cli/src/utils.c +++ b/cli/src/utils.c @@ -13,13 +13,14 @@ #include #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; + 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..293c097 100644 --- a/cli/src/utils.h +++ b/cli/src/utils.h @@ -8,10 +8,9 @@ #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 +20,6 @@ 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/hook/main.go b/hook/main.go index c909114..332a173 100644 --- a/hook/main.go +++ b/hook/main.go @@ -7,7 +7,6 @@ package main import ( "bufio" "encoding/json" - "flag" "fmt" "log" "os" @@ -364,7 +363,6 @@ func doPrestartHook() error { func main() { log.SetPrefix(loggingPrefix) - flag.Parse() if err := doPrestartHook(); err != nil { log.Fatal(err) diff --git a/install/deb/src/main.c b/install/deb/src/main.c index 2be6344..c999836 100644 --- a/install/deb/src/main.c +++ b/install/deb/src/main.c @@ -6,16 +6,22 @@ #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 -#define ADD_CMD_ARGS_NUM 5 +#define MIN_ARGS_NUM 4 +#define ADD_CMD_ARGS_NUM 5 #define ADD_CMD "add" #define RM_CMD "rm" -#define CMD_INDEX 1 -#define FINAL_FILE_INDEX 2 -#define TEMP_FILE_INDEX 3 +#define CMD_INDEX 1 +#define FINAL_FILE_INDEX 2 +#define TEMP_FILE_INDEX 3 #define RUNTIME_PATH_INDEX 4 #define ASCEND_RUNTIME_PATH_KEY "path" #define ASCEND_RUNTIME_ARGS_KEY "runtimeArgs" @@ -23,11 +29,12 @@ #define ASCEND_RUNTIME_NAME "ascend" #define DEFALUT_KEY "default-runtime" #define DEFAULT_VALUE "ascend" +#define ROOT_UID 0 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 +42,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 +56,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 +78,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 +93,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 +120,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 +133,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 +146,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 +154,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 +169,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 +185,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 +195,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 +243,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 +253,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 +268,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 +282,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 != ROOT_UID) && (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 +386,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 +412,19 @@ 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 +432,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 +442,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); @@ -377,13 +474,10 @@ int main(int argc, char *argv[]) printf("%s\n", argv[TEMP_FILE_INDEX]); printf("%s\n", argv[CMD_INDEX]); - if (strcmp(argv[CMD_INDEX], ADD_CMD) == 0) { - if (argc != ADD_CMD_ARGS_NUM) { - return -1; - } - + if ((strcmp(argv[CMD_INDEX], ADD_CMD) == 0) && (argc == ADD_CMD_ARGS_NUM)) { return DetectAndCreateJsonFile(argv[FINAL_FILE_INDEX], argv[TEMP_FILE_INDEX], argv[RUNTIME_PATH_INDEX]); + } else if ((strcmp(argv[CMD_INDEX], RM_CMD) == 0) && (argc == MIN_ARGS_NUM)) { + return CreateRevisedJsonFile(argv[FINAL_FILE_INDEX], argv[TEMP_FILE_INDEX]); } - - return CreateRevisedJsonFile(argv[FINAL_FILE_INDEX], argv[TEMP_FILE_INDEX]); -} + return -1; +} \ No newline at end of file