diff --git a/interfaces/common/src/common_func.cpp b/interfaces/common/src/common_func.cpp index 01307b9ca6fb9db416e5581932d35a90df6a7e01..b894846198f8cceed87ec69bd8e04d2704ca2bb1 100644 --- a/interfaces/common/src/common_func.cpp +++ b/interfaces/common/src/common_func.cpp @@ -110,6 +110,10 @@ static void NormalizePath(string &path) string CommonFunc::GetUriFromPath(const string &path) { + if (!SandboxHelper::IsValidPath(path)) { + LOGE("path is ValidPath"); + return ""; + } if (path.find(FILE_SCHEME_PREFIX) == 0) { return path; } diff --git a/interfaces/common/src/sandbox_helper.cpp b/interfaces/common/src/sandbox_helper.cpp index 863884aa02dbe43c97f73c9a4cc32ba784b26b9a..123e4c4267afbbed5f43ef20017dc8d23f1832e6 100644 --- a/interfaces/common/src/sandbox_helper.cpp +++ b/interfaces/common/src/sandbox_helper.cpp @@ -19,7 +19,6 @@ #include #include #include - #include "log.h" #include "json_utils.h" #include "uri.h" @@ -42,13 +41,16 @@ namespace { const string FILE_MANAGER_AUTHORITY = "docs"; const string DLP_MANAGER_BUNDLE_NAME = "com.ohos.dlpmanager"; const string FUSE_URI_HEAD = "/mnt/data/fuse"; - const string BACKFLASH = "/"; + const char BACKSLASH = '/'; const string MEDIA = "media"; const string NETWORK_ID_FLAG = ""; const string LOCAL = "local"; const int ASSET_IN_BUCKET_NUM_MAX = 1000; const int ASSET_DIR_START_NUM = 16; const int DECODE_FORMAT_NUM = 16; + const std::string PATH_INVALID_FLAG1 = "../"; + const std::string PATH_INVALID_FLAG2 = "/.."; + const uint32_t PATH_INVALID_FLAG_LEN = 3; } struct MediaUriInfo { @@ -302,7 +304,7 @@ static int32_t GetMediaPhysicalPath(const std::string &sandboxPath, const std::s } physicalPath = SHAER_PATH_HEAD + userId + SHAER_PATH_MID + mediaUriInfo.mediaType + - BACKFLASH + to_string(bucketNum) + BACKFLASH + mediaUriInfo.realName + mediaSuffix; + BACKSLASH + to_string(bucketNum) + BACKSLASH + mediaUriInfo.realName + mediaSuffix; return 0; } @@ -342,6 +344,10 @@ static void DoGetPhysicalPath(string &lowerPathTail, string &lowerPathHead, cons int32_t SandboxHelper::GetPhysicalPath(const std::string &fileUri, const std::string &userId, std::string &physicalPath) { + if (!IsValidPath(fileUri)) { + LOGE("fileUri is ValidPath"); + return -EINVAL; + } Uri uri(fileUri); string bundleName = uri.GetAuthority(); if (bundleName == MEDIA) { @@ -378,6 +384,10 @@ int32_t SandboxHelper::GetPhysicalPath(const std::string &fileUri, const std::st int32_t SandboxHelper::GetBackupPhysicalPath(const std::string &fileUri, const std::string &userId, std::string &physicalPath) { + if (!IsValidPath(fileUri)) { + LOGE("fileUri is ValidPath"); + return -EINVAL; + } Uri uri(fileUri); string bundleName = uri.GetAuthority(); if (bundleName == MEDIA) { @@ -411,10 +421,22 @@ int32_t SandboxHelper::GetBackupPhysicalPath(const std::string &fileUri, const s return 0; } -bool SandboxHelper::IsValidPath(const std::string &path) +bool SandboxHelper::IsValidPath(const std::string &filePath) { - if (path.find("/./") != std::string::npos || - path.find("/../") != std::string::npos) { + if (filePath.find("/./") != std::string::npos) { + return false; + } + size_t pos = filePath.find(PATH_INVALID_FLAG1); + while (pos != string::npos) { + if (pos == 0 || filePath[pos - 1] == BACKSLASH) { + LOGE("Relative path is not allowed, path contain ../"); + return false; + } + pos = filePath.find(PATH_INVALID_FLAG1, pos + PATH_INVALID_FLAG_LEN); + } + pos = filePath.rfind(PATH_INVALID_FLAG2); + if ((pos != string::npos) && (filePath.size() - pos == PATH_INVALID_FLAG_LEN)) { + LOGE("Relative path is not allowed, path tail is /.."); return false; } return true; diff --git a/interfaces/innerkits/native/file_uri/src/file_uri.cpp b/interfaces/innerkits/native/file_uri/src/file_uri.cpp index f2af06226bd36679c74b318409e3cd9e0b36ca15..bcc2feb888f2a4ad10eb040ff89eb4d44af1689a 100644 --- a/interfaces/innerkits/native/file_uri/src/file_uri.cpp +++ b/interfaces/innerkits/native/file_uri/src/file_uri.cpp @@ -143,7 +143,8 @@ string FileUri::GetRealPath() string FileUri::GetRealPathBySA(const std::string &targetBundleName) { string sandboxPath = DecodeBySA(uri_.GetPath()); - if (sandboxPath.empty()) { + if (sandboxPath.empty() || !SandboxHelper::IsValidPath(sandboxPath)) { + LOGE("path is ValidPath"); return ""; } string realPath = sandboxPath; @@ -165,6 +166,10 @@ string FileUri::ToString() string FileUri::GetFullDirectoryUri() { string uri = uri_.ToString(); + if (!SandboxHelper::IsValidPath(uri)) { + LOGE("uri is ValidPath"); + return ""; + } struct stat fileInfo; if (stat(GetRealPath().c_str(), &fileInfo) != 0) { LOGE("fileInfo is error,%{public}s", strerror(errno)); @@ -200,6 +205,10 @@ bool FileUri::CheckUriFormat(const std::string &uri) LOGE("URI is missing file://"); return false; } + if (!SandboxHelper::IsValidPath(uri)) { + LOGE("uri is ValidPath"); + return false; + } return true; } diff --git a/utils/src/b_filesystem/b_dir.cpp b/utils/src/b_filesystem/b_dir.cpp index 2845338e4d6086644a0961141591cab2e3846212..629da52d4593f3e3d6aa39b1774f8b58d7d3a915 100644 --- a/utils/src/b_filesystem/b_dir.cpp +++ b/utils/src/b_filesystem/b_dir.cpp @@ -34,6 +34,7 @@ #include "directory_ex.h" #include "errors.h" #include "filemgmt_libhilog.h" +#include "sandbox_helper.h" namespace OHOS::FileManagement::Backup { using namespace std; @@ -41,9 +42,6 @@ const int32_t PATH_MAX_LEN = 4096; const size_t TOP_ELE = 0; const std::string APP_DATA_DIR = BConstants::PATH_PUBLIC_HOME + BConstants::PATH_APP_DATA + BConstants::FILE_SEPARATOR_CHAR; -const std::string PATH_INVALID_FLAG1 = "../"; -const std::string PATH_INVALID_FLAG2 = "/.."; -const uint32_t PATH_INVALID_FLAG_LEN = 3; static bool IsEmptyDirectory(const string &path) { @@ -516,22 +514,7 @@ vector BDir::GetDirs(const vector &paths) bool BDir::IsFilePathValid(const std::string &filePath) { - size_t pos = filePath.find(PATH_INVALID_FLAG1); - while (pos != string::npos) { - if (pos == 0 || filePath[pos - 1] == BConstants::FILE_SEPARATOR_CHAR) { - HILOGE("Relative path is not allowed, path contain ../, path = %{private}s", - GetAnonyString(filePath).c_str()); - return false; - } - pos = filePath.find(PATH_INVALID_FLAG1, pos + PATH_INVALID_FLAG_LEN); - } - pos = filePath.rfind(PATH_INVALID_FLAG2); - if ((pos != string::npos) && (filePath.size() - pos == PATH_INVALID_FLAG_LEN)) { - HILOGE("Relative path is not allowed, path tail is /.., path = %{private}s", - GetAnonyString(filePath).c_str()); - return false; - } - return true; + return AppFileService::SandboxHelper::IsValidPath(filePath); } bool BDir::CheckAndRmSoftLink(const std::string &filePath)