Fix static analysis issue 13/271413/4
authorSangyoon Jang <jeremy.jang@samsung.com>
Mon, 21 Feb 2022 03:31:58 +0000 (12:31 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Tue, 22 Feb 2022 09:22:22 +0000 (18:22 +0900)
Fix TOCTOU problem.

Change-Id: Ie32e21de8e70753484f03e22f27315d581efc1c8
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
server/alarm-manager.c

index ff249831782963604adcf467371fc580bb318651..9b62aba84d59fd06721f960c2410a7bd2975b6e9 100644 (file)
@@ -49,7 +49,8 @@
 #include "alarm-manager-dbus.h"
 
 /* link path for timezone info */
-#define TIMEZONE_INFO_LINK_PATH        tzplatform_mkpath(TZ_SYS_ETC, "localtime")
+#define TIMEZONE_INFO_LINK_DIR_PATH tzplatform_getenv(TZ_SYS_ETC)
+#define TIMEZONE_INFO_LINK_FILE_NAME "localtime"
 
 #ifndef RTC_WKALM_BOOT_SET
 #define RTC_WKALM_BOOT_SET _IOW('p', 0x80, struct rtc_wkalrm)
@@ -2215,6 +2216,7 @@ int alarm_manager_alarm_set_timezone(GVariant* parameters)
        char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,};
        char *tzpath_str;
        time_t cur_time;
+       int dirfd = -1;
 
        g_variant_get(parameters, "(&s)", &tzpath_str);
 
@@ -2226,10 +2228,18 @@ int alarm_manager_alarm_set_timezone(GVariant* parameters)
                goto done;
        }
 
-       retval = lstat(TIMEZONE_INFO_LINK_PATH, &statbuf);
+       dirfd = open(TIMEZONE_INFO_LINK_DIR_PATH, O_DIRECTORY);
+       if (dirfd < 0) {
+               LOGE("open(%s) failed: %d", TIMEZONE_INFO_LINK_DIR_PATH, errno);
+               return_code = ERR_ALARM_SYSTEM_FAIL;
+               goto done;
+       }
+
+       retval = fstatat(dirfd, TIMEZONE_INFO_LINK_FILE_NAME, &statbuf,
+                       AT_SYMLINK_NOFOLLOW);
        if (retval == 0 || (retval == -1 && errno != ENOENT)) {
                /* unlink the current link */
-               if (unlink(TIMEZONE_INFO_LINK_PATH) < 0) {
+               if (unlinkat(dirfd, TIMEZONE_INFO_LINK_FILE_NAME, 0) < 0) {
                        LOGE("unlink() is failed.");
                        return_code = ERR_ALARM_SYSTEM_FAIL;
                        goto done;
@@ -2237,7 +2247,7 @@ int alarm_manager_alarm_set_timezone(GVariant* parameters)
        }
 
        /* create a new symlink when the /opt/etc/localtime is empty. */
-       if (symlink(tzpath_str, TIMEZONE_INFO_LINK_PATH) < 0) {
+       if (symlinkat(tzpath_str, dirfd, TIMEZONE_INFO_LINK_FILE_NAME) < 0) {
                LOGE("Failed to create an symlink of %s.", tzpath_str);
                return_code = ERR_ALARM_SYSTEM_FAIL;
                goto done;
@@ -2270,6 +2280,9 @@ int alarm_manager_alarm_set_timezone(GVariant* parameters)
        bundle_free(b);
 
 done:
+       if (dirfd >= 0)
+               close(dirfd);
+
        if (return_code == ALARMMGR_RESULT_SUCCESS)
                strncpy(log_tag, "SET TIMEZONE", sizeof(log_tag) - 1);
        else