halcc: Fix open_result_file() to receive access mode 77/319177/1 accepted/tizen/9.0/unified/20250207.163728
authorYoungjae Cho <y0.cho@samsung.com>
Tue, 4 Feb 2025 11:03:51 +0000 (20:03 +0900)
committeryoungjae cho <y0.cho@samsung.com>
Wed, 5 Feb 2025 04:46:31 +0000 (04:46 +0000)
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 <y0.cho@samsung.com>
(cherry picked from commit 4fb451b9e55be0ce4dc6f22b115a60172d37203f)

src/hal-api-compatibility-checker.c

index 918715ef3e61ed21197d5c55ac6e26c04d330112..c7d655784963aa0a95a76568d0b35a6b1c585c3f 100644 (file)
@@ -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;