diff options
author | Hyunbin Lee <hyunbin.lee@samsung.com> | 2013-11-26 19:28:19 +0900 |
---|---|---|
committer | Hyunbin Lee <hyunbin.lee@samsung.com> | 2013-12-23 15:55:12 +0900 |
commit | 9fd76ae15cf6ceb781fb7b625984be61cce11934 (patch) | |
tree | fcb4e883b7310bf543a7f5a23a722c9d93a78bef | |
parent | 71d7dd515a1cfc84283af757cc58b5e3aaca06fe (diff) | |
download | env-config-9fd76ae15cf6ceb781fb7b625984be61cce11934.tar.gz env-config-9fd76ae15cf6ceb781fb7b625984be61cce11934.tar.bz2 env-config-9fd76ae15cf6ceb781fb7b625984be61cce11934.zip |
Do private mount temporarily for OSP-compatible applications
Change-Id: I8518618bd69374980ff39f63acf6371bd8fedad1
Signed-off-by: Hyunbin Lee <hyunbin.lee@samsung.com>
-rw-r--r-- | src/osp-env-config.c | 147 |
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; } |