From: Youngjae Cho Date: Tue, 4 Feb 2025 11:03:51 +0000 (+0900) Subject: halcc: Fix open_result_file() to receive access mode X-Git-Tag: accepted/tizen/9.0/unified/20250207.163728^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b2991d29b3c8e7dcff2384a4e357f5ff0a1d21a3;p=platform%2Fhal%2Fapi%2Fcommon.git halcc: Fix open_result_file() to receive access mode The result file is created with permission system_fw:system_fw:0755. It means the previous access mode, which was unconditionally set to O_RDWR, results in permission error if uid is other than system_fw (have no permission to write). But it must be accessible if the caller doesn't intend to write but just read. Therefore, add a parameter so the function opens the file with the given parameter as a flag. Change-Id: I97f3af9ebedb69e75f7e24b057c4a8dfb1a4904d Signed-off-by: Youngjae Cho (cherry picked from commit 4fb451b9e55be0ce4dc6f22b115a60172d37203f) --- diff --git a/src/hal-api-compatibility-checker.c b/src/hal-api-compatibility-checker.c index 918715e..c7d6557 100644 --- a/src/hal-api-compatibility-checker.c +++ b/src/hal-api-compatibility-checker.c @@ -179,19 +179,20 @@ static void convert_hal_to_info_skip_version_check(void *data_hal, void *data_in __convert_hal_to_info(data_hal, data_info, true); } -static int open_result_file(const char *path, int *fd_out) +static int open_result_file(const char *path, int flags, int *fd_out) { - int ret; + int ret = 0; int fd_result = -1; int fd_loaded = -1; - int flags = O_RDWR; if (!fd_out) return -EINVAL; - /* If it is the first access to this file, reset the file. */ - if (access(compatibility_loaded_path, F_OK) != 0) - flags |= O_TRUNC; + /* O_ACCMODE = (O_RDONLY | O_WRONLY | O_RDWR) */ + if (flags & ~O_ACCMODE) { + _W("Drop flags except access mode"); + flags &= O_ACCMODE; + } /** * The file must be there at this moment with proper credentials(onwer,smack) @@ -203,36 +204,57 @@ static int open_result_file(const char *path, int *fd_out) if (fd_result == -1) { ret = -errno; _E("Failed to open %s, %m", path); - return ret; } - /* set the file size */ - ret = ftruncate(fd_result, sizeof(struct compatibility_info) * HAL_MODULE_END); + if (flags == O_RDONLY) + goto out; + + /* Check the compatibility_loaded_path to check the result file has been updated */ + if (access(compatibility_loaded_path, F_OK) == 0) + goto out; + + /* Clear the result file */ + ret = ftruncate(fd_result, 0); if (ret < 0) { ret = -errno; - _E("Failed to ftruncate %s, %m", path); - close(fd_result); - return ret; + _E("Failed to clear file %s, %m", path); + goto fail; } + /* Set the result file size */ + ret = ftruncate(fd_result, sizeof(struct compatibility_info) * HAL_MODULE_END); + if (ret < 0) { + ret = -errno; + _E("Failed to set file size %s, %m", path); + goto fail; + } - /* create file that makes following call not to truncate result file */ + /* Create an empty file that makes following calls not to truncate the result file */ fd_loaded = open(compatibility_loaded_path, O_RDWR | O_CREAT, 0755); if (fd_loaded < 0) { + ret = -errno; _E("Failed to create %s, compatibility info will be incomplete, %m", compatibility_loaded_path); - close(fd_result); - fd_result = -1; - return -errno; + goto fail; } close(fd_loaded); fd_loaded = -1; +out: *fd_out = fd_result; + fd_result = -1; return 0; + +fail: + if (fd_result > 0) { + close(fd_result); + fd_result = -1; + } + + return ret; } static int write_module_comaptibility_info(int fd, enum hal_module module, @@ -274,7 +296,7 @@ static int load_module_compatibility_info(enum hal_module module, return 0; } - ret = open_result_file(compatibility_result_path, &fd); + ret = open_result_file(compatibility_result_path, O_RDONLY, &fd); if (ret < 0) return ret; @@ -346,7 +368,7 @@ static int load_module_compatibility_info_fallback(enum hal_module module, return 0; /* Write all available(initialized) info */ - ret = open_result_file(compatibility_result_path, &fd); + ret = open_result_file(compatibility_result_path, O_RDWR, &fd); if (ret < 0) { _E("Failed to create open result file %s", compatibility_result_path); return ret;