Protect access to parent folders 45/285245/6
authorChanggyu Choi <changyu.choi@samsung.com>
Thu, 8 Dec 2022 05:29:32 +0000 (14:29 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Thu, 8 Dec 2022 07:13:59 +0000 (16:13 +0900)
If file_path is the relative path to the upper folder (e.g., "../") put in,
the operation will be authorized more than API intention.
This patch prevents access to parent folders than the user data folder.

Change-Id: I75852ac321d6b661da91b25cd1c429512d59e7c5
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
src/pkg_cleardata/pkg_cleardata.c

index 0b4b2503ada88dd0edbfee9fd31f352c06a781e9..27ada21dadb8746196f91770742423e1e5cd0615 100644 (file)
@@ -388,11 +388,15 @@ static int __remove_file(const char *pkgid, const char *file_path)
 {
        int ret;
        char filename[PATH_MAX];
+       char user_data_path[PATH_MAX];
+       char path_buf[PATH_MAX];
        const char *rootpath;
+       char *real_path;
        pkgmgrinfo_pkginfo_h pkg_handle = NULL;
        char *pkg_type = NULL;
        struct stat st_file_info;
        char buf[1024] = {0, };
+       int err;
 
        if (pkgid == NULL || file_path == NULL) {
                LOGE("parameter is NULL");
@@ -415,12 +419,32 @@ static int __remove_file(const char *pkgid, const char *file_path)
        tzplatform_set_user(uid);
        rootpath = tzplatform_getenv(TZ_USER_APP);
 
+       snprintf(user_data_path, sizeof(user_data_path), "%s/%s/data/",
+                       rootpath, pkgid);
+
+       snprintf(filename, sizeof(filename), "%s%s", user_data_path, file_path);
+       real_path = realpath(filename, path_buf);
+       err = errno;
+       LOGW("path: %s, real_path, %s", filename, real_path);
+       if (real_path == NULL) {
+               printf("error: %d", err);
+               LOGE("Failed to get realpath. error(%d)", err);
+               ret = -1;
+               goto out;
+       }
+
+       if (strncmp(user_data_path, real_path, strlen(user_data_path)) != 0) {
+               LOGE("Invalid path.(%s)", filename);
+               ret = -1;
+               goto out;
+       }
+
        __send_signal(pkgid, pkg_type,
                        PKGMGR_INSTALLER_START_KEY_STR,
                        PKGMGR_INSTALLER_CLEAR_EVENT_STR);
+       snprintf(user_data_path, sizeof(user_data_path), "%s/%s/data/",
+                       rootpath, pkgid);
 
-       snprintf(filename, sizeof(filename), "%s/%s/data/%s",
-                       rootpath, pkgid, file_path);
        if (lstat(filename, &st_file_info) < 0)
                perror(filename);
 
@@ -445,6 +469,7 @@ static int __remove_file(const char *pkgid, const char *file_path)
 
        }
 
+out:
        tzplatform_reset_user();
        pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
        return ret;