Match-id-3ce9f074c94ae4bba453ca74ae0d9bd6399c3df0

This commit is contained in:
BianTanggui
2022-04-06 14:40:36 +08:00
parent b3acb85963
commit 6cb2eb0ead
5 changed files with 79 additions and 10 deletions

View File

@@ -131,7 +131,7 @@ static bool CheckFileLegality(const char* filePath, const size_t filePathLen,
Logger("realpath failed!", LEVEL_ERROR, SCREEN_YES);
return false;
}
if (strstr(resolvedPath, filePath) == NULL) { // 存在软链接
if (strcmp(resolvedPath, filePath) != 0) { // 存在软链接
Logger("filePath has a soft link!", LEVEL_ERROR, SCREEN_YES);
return false;
}

View File

@@ -37,6 +37,14 @@ int Mount(const char *src, const char *dst)
return -1;
}
}
if (S_ISDIR(fileStat.st_mode) != 0) { // 目录则增加递归校验子集
if (!GetFileSubsetAndCheck(src, strlen(src))) {
char* str = FormatLogMessage("Check file subset failed: %s.", src);
Logger(str, LEVEL_ERROR, SCREEN_YES);
free(str);
return -1;
}
}
ret = mount(src, dst, NULL, mountFlags, NULL);
if (ret < 0) {
Logger("failed to mount src.", LEVEL_ERROR, SCREEN_YES);

View File

@@ -242,9 +242,6 @@ bool CheckExternalFile(const char* filePath, const size_t filePathLen,
if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界
return ShowExceptionInfo("filePathLen out of bounds!");
}
if (strstr(filePath, "..") != NULL) { // 存在".."
return ShowExceptionInfo("filePath has an illegal character!");
}
for (size_t iLoop = 0; iLoop < filePathLen; iLoop++) {
if (!IsValidChar(filePath[iLoop])) { // 非法字符
return ShowExceptionInfo("filePath has an illegal character!");
@@ -254,8 +251,75 @@ bool CheckExternalFile(const char* filePath, const size_t filePathLen,
if (realpath(filePath, resolvedPath) == NULL && errno != ENOENT) {
return ShowExceptionInfo("realpath failed!");
}
if (strstr(resolvedPath, filePath) == NULL) { // 存在软链接
if (strcmp(resolvedPath, filePath) != 0) { // 存在软链接
return ShowExceptionInfo("filePath has a soft link!");
}
return CheckLegality(resolvedPath, strlen(resolvedPath), maxFileSzieMb, checkOwner);
}
static bool CheckFileSubset(const char* filePath, const size_t filePathLen,
const size_t maxFileSzieMb)
{
const unsigned long long maxFileSzieB = maxFileSzieMb * 1024 * 1024;
int iLoop;
if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界
return ShowExceptionInfo("filePathLen out of bounds!");
}
for (iLoop = 0; iLoop < filePathLen; iLoop++) {
if (!IsValidChar(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 (strcmp(resolvedPath, filePath) != 0) { // 存在软链接
return ShowExceptionInfo("filePath has a soft link!");
}
struct stat fileStat;
if (stat(filePath, &fileStat) != 0) {
return ShowExceptionInfo("filePath does not exist or is not a file!");
}
if (fileStat.st_size >= maxFileSzieB) { // 文件大小超限
return ShowExceptionInfo("fileSize out of bounds!");
}
return true;
}
bool GetFileSubsetAndCheck(const char *basePath, const size_t basePathLen)
{
DIR *dir = NULL;
struct dirent *ptr = NULL;
char base[PATH_MAX] = {0};
if ((dir = opendir(basePath)) == NULL) {
return ShowExceptionInfo("Open dir error!");
}
while ((ptr = readdir(dir)) != NULL) {
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
continue;
}
memset_s(base, PATH_MAX, 0, PATH_MAX);
if (strcpy_s(base, PATH_MAX, basePath) != 0) {
return ShowExceptionInfo("Strcpy failed!");
}
if (strcat_sp(base, PATH_MAX, "/") != 0 ||
strcat_sp(base, PATH_MAX, ptr->d_name) != 0) {
return ShowExceptionInfo("Strcat failed!");
}
if (ptr->d_type == DT_REG) { // 文件
const size_t maxFileSzieMb = 10; // max 10 MB
if (!CheckFileSubset(base, strlen(base), maxFileSzieMb)) {
return false;
}
} else if (ptr->d_type == DT_LNK) { // 软链接
return ShowExceptionInfo("FilePath has a soft link!");
} else if (ptr->d_type == DT_DIR) { // 目录
if (!GetFileSubsetAndCheck(base, strlen(base))) {
return false;
}
}
}
return true;
}

View File

@@ -25,5 +25,5 @@ int MakeMountPoints(const char *path, mode_t mode);
bool IsValidChar(const char c);
bool CheckExternalFile(const char* filePath, const size_t filePathLen,
const size_t maxFileSzieMb, const bool checkOwner);
bool GetFileSubsetAndCheck(const char *basePath, const size_t basePathLen);
#endif

View File

@@ -331,7 +331,7 @@ static bool IsValidChar(const char c)
if (isalnum(c) != 0) {
return true;
}
// ._-/~为合法字符
if ((c == '.') || (c == '_') ||
(c == '-') || (c == '/') || (c == '~')) {
return true;
@@ -345,9 +345,6 @@ static bool CheckExternalFile(const char* filePath, const size_t filePathLen,
if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界
return ShowExceptionInfo("filePathLen out of bounds!");
}
if (strstr(filePath, "..") != NULL) { // 存在".."
return ShowExceptionInfo("filePath has an illegal character!");
}
for (size_t iLoop = 0; iLoop < filePathLen; iLoop++) {
if (!IsValidChar(filePath[iLoop])) { // 非法字符
return ShowExceptionInfo("filePath has an illegal character!");