From: Szymon Jastrzebski Date: Mon, 15 Jan 2018 08:19:22 +0000 (+0100) Subject: [Common] Adding macro to check file access X-Git-Tag: submit/tizen/20180205.083005~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F77%2F167077%2F10;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Common] Adding macro to check file access [Verification] The macro works as intended on applications with required version 4.0 and 5.0. Change-Id: I2d530cd6c2447616bb963fb3640bd16b8b1b8fd9 Signed-off-by: Szymon Jastrzebski --- diff --git a/src/common/tools.cc b/src/common/tools.cc index c1d49984..5ef95ca1 100644 --- a/src/common/tools.cc +++ b/src/common/tools.cc @@ -446,6 +446,23 @@ bool IsAppVersionEarlierThan(const std::string& ver) { return false; } +/* + * RequestStoragePrivilegeChecker structure is used to check whether the file stating is needed. + * File stating is done to ensure that the application has given access to files on + * internal/external memory. The checking is done since Tizen 5.0 for applications, which + * require at least 5.0 version of Tizen. + * */ +struct RequestStoragePrivilegeChecker { + bool isStorageAccessCheckNeeded; + RequestStoragePrivilegeChecker() : isStorageAccessCheckNeeded(!IsAppVersionEarlierThan("5.0")) { + } +}; + +bool IsStoragePrivilegeCheckNeeded() { + static RequestStoragePrivilegeChecker checker{}; + return checker.isStorageAccessCheckNeeded; +} + std::string GetErrorString(int error_code) { static const size_t kSize = 1024; char msg[kSize] = {0}; @@ -491,6 +508,39 @@ bool IsPathValid(const std::string& path) { path.length() - 3 != path.rfind("/.."); } +PlatformResult CheckStorageAccess(const std::string& path) { + ScopeLogger("path: [%s]", path.c_str()); + struct stat buf {}; + char* real_path = realpath(path.c_str(), nullptr); + SCOPE_EXIT { + free(real_path); + }; + if ((nullptr == real_path && EACCES == errno) || + (-1 == stat(real_path, &buf) && EACCES == errno)) { + LoggerE("The application does not have necessary privilege to access given file: [%s]", + path.c_str()); + return PlatformResult(ErrorCode::SECURITY_ERR, + "Permission denied: accessing files requires proper storage privilege"); + } + return PlatformResult(ErrorCode::NO_ERROR); +} + +TizenResult CheckStorageAccessAndReturn(const std::string& path) { + ScopeLogger("path: [%s]", path.c_str()); + struct stat buf {}; + char* real_path = realpath(path.c_str(), nullptr); + SCOPE_EXIT { + free(real_path); + }; + if ((nullptr == real_path && EACCES == errno) || + (-1 == stat(real_path, &buf) && EACCES == errno)) { + LoggerE("The application does not have necessary privilege to access given file: [%s]", + path.c_str()); + return SecurityError("Permission denied: accessing files requires proper storage privilege"); + } + return TizenSuccess(); +} + PlatformResult CheckFileStatus(const std::string& path) { ScopeLogger(); diff --git a/src/common/tools.h b/src/common/tools.h index d72a09b8..88136c48 100644 --- a/src/common/tools.h +++ b/src/common/tools.h @@ -23,6 +23,7 @@ #include "common/picojson.h" #include "common/platform_exception.h" #include "common/platform_result.h" +#include "common/tizen_result.h" namespace common { namespace tools { @@ -35,8 +36,10 @@ void ReportError(const PlatformResult& error, picojson::object* out); common::PlatformResult CheckAccess(const std::string& privilege); common::PlatformResult CheckAccess(const std::vector& privileges); +common::PlatformResult CheckStorageAccess(const std::string& path); +common::TizenResult CheckStorageAccessAndReturn(const std::string& path); common::PlatformResult GetPkgApiVersion(std::string* api_version); - +bool IsStoragePrivilegeCheckNeeded(); bool IsAppVersionEarlierThan(const std::string& ver); // it is used for modules which return TizenResult objects to JS layer @@ -57,6 +60,29 @@ bool IsAppVersionEarlierThan(const std::string& ver); } \ } while (0) +// The below macro is designed to check, whether the application has necessary privilege in order +// to access resource on internal or external memory. +#define CHECK_STORAGE_ACCESS(path, out) \ + do { \ + if (common::tools::IsStoragePrivilegeCheckNeeded()) { \ + auto ret = common::tools::CheckStorageAccess(path); \ + if (!ret) { \ + common::tools::ReportError(ret, out); \ + return; \ + } \ + } \ + } while (0) + +#define CHECK_STORAGE_ACCESS_AND_RETURN(path) \ + do { \ + if (common::tools::IsStoragePrivilegeCheckNeeded()) { \ + auto ret = common::tools::CheckStorageAccessAndReturn(path); \ + if (!ret) { \ + return ret; \ + } \ + } \ + } while (0) + #define CHECK_BACKWARD_COMPABILITY_PRIVILEGE_ACCESS(current_priv, prev_priv, out) \ do { \ auto ret = common::tools::CheckAccess(current_priv); \