From d67185370c8e2c0c3db6ee76545c7589cc94b663 Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Tue, 11 Jan 2022 17:20:08 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=B0=86=E5=BD=93=E5=89=8Dapp=E7=9A=84?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E5=8A=A0=E5=85=A5mount=20namespace,=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=B8=8D=E5=90=8Capp=E4=B9=8B=E9=97=B4?= =?UTF-8?q?=E7=9A=84=E6=8C=82=E8=BD=BD=E7=82=B9=E9=9A=94=E7=A6=BB=E3=80=82?= =?UTF-8?q?=202.=20app=E7=9C=8B=E5=88=B0=E7=9A=84=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=B7=B2=E7=BB=8F=E4=B8=8D=E6=98=AF=E5=8E=9F=E5=A7=8B=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=B7=AF=E5=BE=84=EF=BC=8C=E8=80=8C=E6=98=AF?= =?UTF-8?q?=E5=81=9A=E4=BA=86=E4=B8=80=E6=AC=A1bind=20mount=EF=BC=8C?= =?UTF-8?q?=E4=B9=8B=E5=90=8E=E8=BF=9B=E8=A1=8Cpivot=5Froot=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=B9=8B=E5=90=8E=E5=BE=97=E5=88=B0=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=B7=AF=E5=BE=84=E3=80=82=203.=20=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E6=94=B9=E5=8A=A8=E4=B8=8D=E5=BD=B1=E5=93=8D=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=8C=E5=AF=B9=E4=BA=8E=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=B8=8D=E6=84=9F=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Zheng Yongjun Change-Id: Ie7bf4eaeed7a41e66b3584438dcee8e66d931aaa --- src/appspawn_server.cpp | 164 +++++++++++++++++++++++++++++++++- src/include/appspawn_server.h | 20 +++++ 2 files changed, 182 insertions(+), 2 deletions(-) diff --git a/src/appspawn_server.cpp b/src/appspawn_server.cpp index 2acb6818..4807ae3e 100644 --- a/src/appspawn_server.cpp +++ b/src/appspawn_server.cpp @@ -19,9 +19,13 @@ #include #include #include +#include #include #include +#include #include +#include +#include #include "errors.h" #include "hilog/log.h" @@ -30,8 +34,11 @@ #include #include +#include +#include #define GRAPHIC_PERMISSION_CHECK +constexpr static mode_t FILE_MODE = 0711; namespace OHOS { namespace AppSpawn { @@ -95,14 +102,14 @@ static void InstallSigHandler() static void UninstallSigHandler() { struct sigaction sa = {}; - sa.sa_handler = SIG_DFL; + sa.sa_handler = nullptr; int err = sigaction(SIGCHLD, &sa, nullptr); if (err < 0) { HiLog::Error(LABEL, "Error uninstalling SIGCHLD handler: %d", errno); } struct sigaction sah = {}; - sah.sa_handler = SIG_DFL; + sah.sa_handler = nullptr; err = sigaction(SIGHUP, &sah, nullptr); if (err < 0) { HiLog::Error(LABEL, "Error uninstalling SIGHUP handler: %d", errno); @@ -386,6 +393,151 @@ void AppSpawnServer::SetServerSocket(const std::shared_ptr &server socket_ = serverSocket; } +int32_t AppSpawnServer::DoAppSandboxMountOnce(const std::string originPath, const std::string destinationPath) +{ + int rc = 0; + + rc = mount(originPath.c_str(), destinationPath.c_str(), NULL, MS_BIND, NULL); + if (rc) { + return rc; + } + + rc = mount(NULL, destinationPath.c_str(), NULL, MS_PRIVATE, NULL); + if (rc) { + return rc; + } + + return 0; +} + +int32_t AppSpawnServer::DoAppSandboxMount(const ClientSocket::AppProperty *appProperty, std::string rootPath) +{ + std::string oriInstallPath = "/data/app/el1/bundle/"; + std::string oriDataPath = "/data/app/el2/0/base/"; + std::string oriDatabasePath = "/data/app/el2/0/database/"; + std::string destAPI7InstallPath = rootPath + "/data/accounts/account_0/applications"; + std::string destDatabasePath = rootPath + "/data/storage/el2/database"; + std::string destInstallPath = rootPath + "/data/storage/el1/0/bundle"; + std::string destDataPath = rootPath + "/data/storage/el2/base"; + int rc = 0; + + oriInstallPath += appProperty->processName; + oriDataPath += appProperty->processName; + oriDatabasePath += appProperty->processName; + + std::map mountMap; + mountMap[oriInstallPath] = destAPI7InstallPath; + mountMap[oriDatabasePath] = destDatabasePath; + mountMap[oriInstallPath] = destInstallPath; + mountMap[oriDataPath] = destDataPath; + + std::map::iterator iter; + for (iter = mountMap.begin(); iter != mountMap.end(); iter++) { + rc = DoAppSandboxMountOnce(iter->first.c_str(), iter->second.c_str()); + if (rc) { + return rc; + } + } + + return 0; +} + +void AppSpawnServer::DoAppSandboxMkdir(std::string sandboxPackagePath, const ClientSocket::AppProperty *appProperty) +{ + // to create /mnt/sandbox//data/storage/el1 related path, later should delete this code. + std::string dirPath = sandboxPackagePath + "/data/"; + + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage/el1"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage/el1/0"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage/el1/0/bundle"; + mkdir(dirPath.c_str(), FILE_MODE); + + // to create /mnt/sandbox//data/storage/el1 related path, later should delete this code. + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage/el2"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage/el2/base"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/storage/el2/database"; + mkdir(dirPath.c_str(), FILE_MODE); + + // create applications folder for compatibility purpose + dirPath = sandboxPackagePath + "/data/accounts"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/accounts/account_0"; + mkdir(dirPath.c_str(), FILE_MODE); + dirPath = sandboxPackagePath + "/data/accounts/account_0/applications"; + mkdir(dirPath.c_str(), FILE_MODE); +} + +int32_t AppSpawnServer::SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty) +{ + int rc = 0; + + // create /mnt/sandbox/ path, later put it to rootfs module + std::string sandboxPackagePath = "/mnt/sandbox/"; + mkdir(sandboxPackagePath.c_str(), FILE_MODE); + sandboxPackagePath += appProperty->processName; + mkdir(sandboxPackagePath.c_str(), FILE_MODE); + + // add pid to a new mnt namespace + rc = unshare(CLONE_NEWNS); + if (rc) { + HiLog::Error(LABEL, "unshare failed, packagename is %{public}s", appProperty->processName); + return rc; + } + + rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL); + if (rc) { + HiLog::Error(LABEL, "set propagation slave failed, packagename is %{public}s", appProperty->processName); + return rc; + } + + // bind mount "/" to /mnt/sandbox/ path + // rootfs: to do more resouces bind mount here to get more strict resources constraints + rc = mount("/", sandboxPackagePath.c_str(), NULL, MS_BIND | MS_REC, NULL); + if (rc) { + HiLog::Error(LABEL, "mount bind / failed, packagename is %{public}s", appProperty->processName); + return rc; + } + + // to create /mnt/sandbox//data/storage related path + DoAppSandboxMkdir(sandboxPackagePath, appProperty); + + rc = DoAppSandboxMount(appProperty, sandboxPackagePath); + if (rc) { + HiLog::Error(LABEL, "DoAppSandboxMount failed, packagename is %{public}s", appProperty->processName); + return rc; + } + + rc = chdir(sandboxPackagePath.c_str()); + if (rc) { + HiLog::Error(LABEL, "chdir failed, packagename is %{public}s, path is %{public}s", \ + appProperty->processName, sandboxPackagePath.c_str()); + return rc; + } + + rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); + if (rc) { + HiLog::Error(LABEL, "pivot root failed, packagename is %{public}s, errno is %{public}d", \ + appProperty->processName, errno); + return rc; + } + + rc = umount2(".", MNT_DETACH); + if (rc) { + HiLog::Error(LABEL, "MNT_DETACH failed, packagename is %{public}s", appProperty->processName); + return rc; + } + + return ERR_OK; +} + bool AppSpawnServer::SetAppProcProperty(int connectFd, const ClientSocket::AppProperty *appProperty, char *longProcName, int64_t longProcNameLen, const int32_t fd[FDLEN2]) { @@ -393,6 +545,7 @@ bool AppSpawnServer::SetAppProcProperty(int connectFd, const ClientSocket::AppPr HiLog::Error(LABEL, "appProperty is nullptr"); return false; } + pid_t newPid = getpid(); HiLog::Debug(LABEL, "AppSpawnServer::Success to fork new process, pid = %{public}d", newPid); // close socket connection and peer socket in child process @@ -402,6 +555,13 @@ bool AppSpawnServer::SetAppProcProperty(int connectFd, const ClientSocket::AppPr UninstallSigHandler(); int32_t ret = ERR_OK; + + ret = SetAppSandboxProperty(appProperty); + if (FAILED(ret)) { + NotifyResToParentProc(fd[1], ret); + return false; + } + ret = SetKeepCapabilities(appProperty->uid); if (FAILED(ret)) { NotifyResToParentProc(fd[1], ret); diff --git a/src/include/appspawn_server.h b/src/include/appspawn_server.h index 8ec61909..bb61bb83 100644 --- a/src/include/appspawn_server.h +++ b/src/include/appspawn_server.h @@ -122,6 +122,26 @@ private: */ int32_t SetCapabilities(); + /** + * Do app sandbox original path mount common + */ + int32_t DoAppSandboxMountOnce(const std::string originPath, const std::string destinationPath); + + /** + * Do app sandbox original path mount + */ + int32_t DoAppSandboxMount(const ClientSocket::AppProperty *appProperty, std::string rootPath); + + /** + * Do app sandbox mkdir /mnt/sandbox// + */ + void DoAppSandboxMkdir(std::string rootPath, const ClientSocket::AppProperty *appProperty); + + /** + * Sets app sandbox property. + */ + int32_t SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty); + /** * Sets app process property. */ -- Gitee