summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/osp-env-config.c147
1 files changed, 139 insertions, 8 deletions
diff --git a/src/osp-env-config.c b/src/osp-env-config.c
index b42c102..198c005 100644
--- a/src/osp-env-config.c
+++ b/src/osp-env-config.c
@@ -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;
}