Do private mount temporarily for OSP-compatible applications 89/14089/1
authorHyunbin Lee <hyunbin.lee@samsung.com>
Tue, 26 Nov 2013 10:28:19 +0000 (19:28 +0900)
committerHyunbin Lee <hyunbin.lee@samsung.com>
Mon, 23 Dec 2013 06:55:12 +0000 (15:55 +0900)
Change-Id: I8518618bd69374980ff39f63acf6371bd8fedad1
Signed-off-by: Hyunbin Lee <hyunbin.lee@samsung.com>
src/osp-env-config.c

index b42c102..198c005 100644 (file)
@@ -32,6 +32,7 @@
 #include <sys/vfs.h>
 #include <fcntl.h>
 #include <dlfcn.h>
+#include <mntent.h>
 
 #include <dlog.h>
 #include <vconf.h>
@@ -243,7 +244,7 @@ mount_native_paths(const char* app_rootpath)
 
        for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
        {
-               if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
+               if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
                {
                        LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
                                        mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
@@ -297,7 +298,7 @@ mount_osp_internal_paths(const char* app_rootpath, const char* pkgid)
 
        for (i = 0; i < sizeof(mount_info1)/sizeof(struct _path_info); ++i)
        {
-               if (mount(mount_info1[i].src_path, mount_info1[i].dest_path, NULL, MS_BIND, NULL) != 0)
+               if (mount(mount_info1[i].src_path, mount_info1[i].dest_path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
                {
                        LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
                                        mount_info1[i].src_path, mount_info1[i].dest_path, errno, strerror(errno));
@@ -312,7 +313,7 @@ mount_osp_internal_paths(const char* app_rootpath, const char* pkgid)
        }
        for (i = 0; i < sizeof(mount_info2)/sizeof(struct _path_info); ++i)
        {
-               if (mount(mount_info2[i].src_path, mount_info2[i].dest_path, NULL, MS_BIND, NULL) != 0)
+               if (mount(mount_info2[i].src_path, mount_info2[i].dest_path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
                {
                        LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
                                        mount_info2[i].src_path, mount_info2[i].dest_path, errno, strerror(errno));
@@ -385,7 +386,7 @@ mount_linux_paths(const char* app_rootpath)
                }
 
                LOGI("src path: %s, dest path: %s", mount_info[i].src_path, mount_info[i].dest_path);
-               if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
+               if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
                {
                        LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
                                        mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
@@ -492,7 +493,7 @@ mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
        char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
        char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
        char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
-       struct _path_info mount_info1[] =
+       const struct _path_info mount_info1[] =
        {
                { "/opt/storage/sdcard",                        "./Storagecard/Media"   },
                { "/opt/storage/sdcard/osp/share",      "./ShareExt"                    },
@@ -531,7 +532,7 @@ mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
 
        for (i = 0; i < sizeof(mount_info1)/sizeof(struct _path_info); i++)
        {
-               if (mount(mount_info1[i].src_path, mount_info1[i].dest_path, NULL, MS_BIND, NULL) != 0)
+               if (mount(mount_info1[i].src_path, mount_info1[i].dest_path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
                {
                        LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
                                        mount_info1[i].src_path, mount_info1[i].dest_path, errno, strerror(errno));
@@ -546,7 +547,7 @@ mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
        }
        for (i = 0; i < sizeof(mount_info2)/sizeof(struct _path_info); i++)
        {
-               if (mount(mount_info2[i].src_path, mount_info2[i].dest_path, NULL, MS_BIND, NULL) != 0)
+               if (mount(mount_info2[i].src_path, mount_info2[i].dest_path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
                {
                        LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
                                        mount_info2[i].src_path, mount_info2[i].dest_path, errno, strerror(errno));
@@ -563,6 +564,94 @@ mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
        return 0;
 }
 
+static int
+find_device_node(const char* path, char* buf, int buflen)
+{
+       const char table[] = "/etc/mtab";
+       struct mntent ent;
+       int found = 0;
+
+       if (strlen(path) >= PATH_MAX)
+       {
+               SECURE_LOGE("The specified path (%s) is too long. length: %d", path, strlen(path));
+               return -EINVAL;
+       }
+
+       FILE* fp = setmntent(table, "r");
+       if (fp == NULL)
+       {
+               LOGE("Calling setmntent() with %s failed.", table);
+               return -ENOMEM;
+       }
+
+       while (getmntent_r(fp, &ent, buf, buflen))
+       {
+               //LOGI("path: %s, device node: %s", ent.mnt_dir, buf);
+               if (strncmp(ent.mnt_dir, path, strlen(path)) == 0)
+               {
+                       found = 1;
+                       break;
+               }
+       }
+
+       endmntent(fp);
+
+       if (found == 0)
+       {
+               LOGE("Device node does not exist. path: %s", path);
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+static int
+change_mount_mode(unsigned long mountflags)
+{
+       char dev_node[PATH_MAX] = { 0, };
+       static const char dir[][32] =
+       {
+               { "/" },
+               { "/dev" },
+               { "/opt" },
+               { "/opt/storage/sdcard" },
+               { "/opt/usr" },
+               { "/opt/var/run" },
+               { "/sys" },
+               { "/usr/share/locale" },
+               { "/var" }
+       };
+
+       int i = 0;
+       for (i = 0; i < sizeof(dir)/32; ++i)
+       {
+               //LOGI("dir: %s", dir[i]);
+               int res = find_device_node(dir[i], dev_node, PATH_MAX - 1);
+               if (res == 0)
+               {
+                       int ret = mount(dev_node, dir[i], NULL, mountflags, NULL);
+                       if (ret != 0)
+                       {
+                               LOGE("Changing mount mode failed. ret: %d, errno: %d (%s)", ret, errno, strerror(errno));
+                               return -1;
+                       }
+               }
+               else if (res == -ENOENT)
+               {
+                       continue;
+               }
+               else
+               {
+                       LOGE("Finding device node failed.");
+                       return -1;
+               }
+
+               memset(dev_node, '\0', PATH_MAX);
+       }
+
+       return 0;
+}
+
 int
 do_pre_exe(const char* app_rootpath, const char* package_id)
 {
@@ -577,6 +666,13 @@ do_pre_exe(const char* app_rootpath, const char* package_id)
 
        umask(0000);
 
+       int ret = change_mount_mode(MS_PRIVATE);
+       if (ret != 0)
+       {
+               LOGE("Changing to private mount mode is failed. ret: %d", ret);
+               goto ERROR;
+       }
+
        if (!internal_is_mounted(package_id))
        {
                if (mount_native_paths(app_rootpath) != 0)
@@ -589,7 +685,7 @@ do_pre_exe(const char* app_rootpath, const char* package_id)
                }
        }
 
-       int ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
+       ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
        if (ret < 0)
        {
                LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
@@ -610,6 +706,14 @@ do_pre_exe(const char* app_rootpath, const char* package_id)
                        }
                }
        }
+
+       ret = change_mount_mode(MS_SHARED);
+       if (ret != 0)
+       {
+               LOGE("Changing to shared mount mode is failed. ret: %d", ret);
+               goto ERROR;
+       }
+
        LOGI("mount() succeeded.");
 
        if (chroot(app_rootpath) != 0)
@@ -638,6 +742,12 @@ do_pre_exe(const char* app_rootpath, const char* package_id)
 ERROR:
        umask(0022);
 
+       ret = change_mount_mode(MS_SHARED);
+       if (ret != 0)
+       {
+               LOGE("Restoring mount mode is failed. ret: %d", ret);
+       }
+
        LOGI("[data_caging] do_pre_exe() failed.");
        return -1;
 }
@@ -650,6 +760,13 @@ do_virtual_root(const char* virtual_root_path, const char* package_id)
 
        umask(0000);
 
+       int ret = change_mount_mode(MS_PRIVATE);
+       if (ret != 0)
+       {
+               LOGE("Changing to private mount mode is failed. ret: %d", ret);
+               goto ERROR;
+       }
+
        if (!internal_is_mounted(package_id))
        {
                if (mount_linux_paths(virtual_root_path) != 0)
@@ -657,6 +774,14 @@ do_virtual_root(const char* virtual_root_path, const char* package_id)
                        goto ERROR;
                }
        }
+
+       ret = change_mount_mode(MS_SHARED);
+       if (ret != 0)
+       {
+               LOGE("Changing to shared mount mode is failed. ret: %d", ret);
+               goto ERROR;
+       }
+
        LOGI("mount() succeeded.");
 
        if (chroot(virtual_root_path) != 0)
@@ -679,6 +804,12 @@ do_virtual_root(const char* virtual_root_path, const char* package_id)
 ERROR:
        umask(0022);
 
+       ret = change_mount_mode(MS_SHARED);
+       if (ret != 0)
+       {
+               LOGE("Restoring mount mode is failed. ret: %d", ret);
+       }
+
        LOGI("[virtual_root] do_virtual_root() failed.");
        return -1;
 }