#include <sys/vfs.h>
#include <fcntl.h>
#include <dlfcn.h>
+#include <mntent.h>
#include <dlog.h>
#include <vconf.h>
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));
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));
}
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));
}
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));
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" },
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));
}
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));
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)
{
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)
}
}
- 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.");
}
}
}
+
+ 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)
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;
}
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)
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)
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;
}