--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/**
+ * @file mount-namespace.h
+ * @author Dariusz Michaluk <d.michaluk@samsung.com>
+ * @version 1.0
+ * @brief Mount namespace utility.
+ *
+ */
+#pragma once
+
+#include <string>
+#include <map>
+#include <vector>
+
+namespace SecurityManager {
+namespace MountNS {
+
+typedef std::string Path;
+typedef std::vector<Path> PathVector;
+typedef std::map<std::string, PathVector> PrivilegePathsMap;
+
+extern const std::string EXTERNAL_STORAGE_PRIVILEGE;
+extern const std::string MEDIA_STORAGE_PRIVILEGE;
+
+extern const std::string MAIN_MOUNT_NAMESPACE;
+
+extern const std::string ACCESS_DENIED_DIR_PATH;
+extern const std::string EXTERNAL_STORAGE_DIR_PATH;
+extern const std::string MEDIA_STORAGE_DIR_PATH;
+
+PrivilegePathsMap getPrivilegePathMap(uid_t uid);
+
+std::string getUsersAppsMountPointsPath(void);
+std::string getUserAppsMountPointsPath(uid_t uid);
+std::string getUserAppMountPointPath(uid_t uid, const std::string &appName);
+
+bool isMountNamespaceEnabled(void);
+int createMountNamespace(void);
+bool enterMountNamespace(const Path &mntPath);
+int makeMountSlave(const Path &mountPoint);
+int makeMountPrivate(const Path &mountPoint);
+int bindMount(const Path &source, const Path &target);
+int uMount(const Path &target);
+bool isPathBound(const Path &what, const Path &where);
+
+} // namespace MountNS
+} // namespace SecurityManager
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/**
+ * @file mount-namespace.cpp
+ * @author Dariusz Michaluk <d.michaluk@samsung.com>
+ * @version 1.0
+ * @brief Mount namespace utility.
+ *
+ */
+
+#include <pwd.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <mount-namespace.h>
+#include <filesystem.h>
+#include <tzplatform-config.h>
+#include <dpl/log/log.h>
+#include <dpl/errno_string.h>
+#include <security-manager.h>
+
+namespace SecurityManager {
+namespace MountNS {
+
+const std::string EXTERNAL_STORAGE_PRIVILEGE = "http://tizen.org/privilege/externalstorage";
+const std::string MEDIA_STORAGE_PRIVILEGE = "http://tizen.org/privilege/mediastorage";
+
+const std::string MAIN_MOUNT_NAMESPACE = "/proc/1/ns/mnt";
+
+const std::string ACCESS_DENIED_DIR_PATH = TizenPlatformConfig::makePath(
+ TZ_SYS_RO_SHARE, "security-manager", "dummy");
+const std::string EXTERNAL_STORAGE_DIR_PATH = TizenPlatformConfig::getEnv(TZ_SYS_STORAGE);
+const std::string MEDIA_STORAGE_DIR_PATH = "/opt/usr/media";
+
+PrivilegePathsMap getPrivilegePathMap(uid_t uid)
+{
+ return
+ {{EXTERNAL_STORAGE_PRIVILEGE, {EXTERNAL_STORAGE_DIR_PATH}},
+ {MEDIA_STORAGE_PRIVILEGE, {TizenPlatformConfig(uid).ctxGetEnv(TZ_USER_CONTENT),
+ MEDIA_STORAGE_DIR_PATH}}};
+}
+
+std::string getUsersAppsMountPointsPath(void)
+{
+ return TizenPlatformConfig::makePath(TZ_SYS_RUN, "user");
+}
+
+std::string getUserAppsMountPointsPath(uid_t uid)
+{
+ return TizenPlatformConfig::makePath(TZ_SYS_RUN, "user", std::to_string(uid), "apps");
+}
+
+std::string getUserAppMountPointPath(uid_t uid, const std::string &appName)
+{
+ return getUserAppsMountPointsPath(uid) + "/" + appName;
+}
+
+bool isMountNamespaceEnabled(void)
+{
+ auto getStatus = []() -> bool {
+ return (access("/proc/self/ns/mnt", F_OK) != -1) ? true : false;
+ };
+
+ static bool isMountNamespaceEnabled = getStatus();
+
+ return isMountNamespaceEnabled;
+}
+
+int createMountNamespace(void)
+{
+ int ret = unshare(CLONE_NEWNS);
+ if (ret != 0) {
+ LogError("Failed to unshare mount namespace: " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+bool enterMountNamespace(const Path &mntPath)
+{
+ int fd = open(mntPath.c_str(), O_RDONLY);
+ if (-1 == fd)
+ return false;
+
+ // 0 == allow any type of namespace
+ int ret = setns(fd, 0);
+ close(fd);
+
+ return ret != -1;
+}
+
+int makeMountSlave(const Path &mountPoint)
+{
+ int ret = mount("none", mountPoint.c_str(), NULL, MS_REC|MS_SLAVE, NULL);
+ if (ret != 0) {
+ LogError("Failed to make mount point " << mountPoint << " slave: " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+int makeMountPrivate(const Path &mountPoint)
+{
+ int ret = mount("none", mountPoint.c_str(), NULL, MS_PRIVATE, NULL);
+ if (ret != 0) {
+ LogError("Failed to make mount point " << mountPoint << " private: " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+int bindMount(const Path &source, const Path &target)
+{
+ int ret = mount(source.c_str(), target.c_str(), NULL, MS_BIND, NULL);
+ if (ret != 0) {
+ LogError("Failed to bind directory " << source << "to " << target << " " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+int uMount(const Path &target)
+{
+ int ret = umount(target.c_str());
+ if (ret != 0) {
+ LogWarning("Failed to umount: " << target << " " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+bool isPathBound(const Path &what, const Path &where)
+{
+ std::string line = what + " " + where;
+ std::string mountinfo = FS::getTextFileContents("/proc/self/mountinfo");
+ return std::string::npos != mountinfo.find(line);
+}
+
+} // namespace MountNS
+} // namespace SecurityManager