diff --git a/PrivateVolume.cpp b/PrivateVolume.cpp index 42eea64..f652c6b 100644 --- a/PrivateVolume.cpp +++ b/PrivateVolume.cpp @@ -43,7 +43,6 @@ PrivateVolume::PrivateVolume(dev_t device, const std::string& keyRaw) : VolumeBase(Type::kPrivate), mRawDevice(device), mKeyRaw(keyRaw) { setId(StringPrintf("private:%u,%u", major(device), minor(device))); mRawDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str()); - mPath = StringPrintf("/mnt/secure/%s", getId().c_str()); } PrivateVolume::~PrivateVolume() { @@ -101,16 +100,17 @@ status_t PrivateVolume::doMount() { return -EIO; } - if (Ext4::check(mDmDevPath.c_str(), mPath.c_str())) { - PLOG(ERROR) << getId() << " failed filesystem check"; - return -EIO; - } - + mPath = StringPrintf("/mnt/expand/%s", mFsUuid.c_str()); setPath(mPath); - if (fs_prepare_dir(mPath.c_str(), 0700, AID_ROOT, AID_ROOT)) { + if (PrepareDir(mPath, 0700, AID_ROOT, AID_ROOT)) { PLOG(ERROR) << getId() << " failed to create mount point " << mPath; - return -errno; + return -EIO; + } + + if (Ext4::check(mDmDevPath.c_str(), mPath.c_str())) { + PLOG(ERROR) << getId() << " failed filesystem check"; + return -EIO; } if (Ext4::doMount(mDmDevPath.c_str(), mPath.c_str(), false, false, true)) { @@ -118,6 +118,16 @@ status_t PrivateVolume::doMount() { return -EIO; } + // Verify that common directories are ready to roll + if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) || + PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) || + PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) || + PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) || + PrepareDir(mPath + "/local/tmp", 0771, AID_SHELL, AID_SHELL)) { + PLOG(ERROR) << getId() << " failed to prepare"; + return -EIO; + } + return OK; } diff --git a/PublicVolume.cpp b/PublicVolume.cpp index ffcfc67..6192e7a 100644 --- a/PublicVolume.cpp +++ b/PublicVolume.cpp @@ -110,7 +110,7 @@ status_t PublicVolume::doMount() { // Use UUID as stable name, if available std::string stableName = getId(); if (!mFsUuid.empty()) { - stableName = "public:" + mFsUuid; + stableName = mFsUuid; } mRawPath = StringPrintf("/mnt/media_rw/%s", stableName.c_str()); diff --git a/Utils.cpp b/Utils.cpp index 2b02f91..1937c28 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -85,26 +85,53 @@ status_t DestroyDeviceNode(const std::string& path) { } } +status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) { + const char* cpath = path.c_str(); + + char* secontext = nullptr; + if (sehandle) { + if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) { + setfscreatecon(secontext); + } + } + + int res = fs_prepare_dir(cpath, mode, uid, gid); + + if (secontext) { + setfscreatecon(nullptr); + freecon(secontext); + } + + if (res == 0) { + return OK; + } else { + return -errno; + } +} + status_t ForceUnmount(const std::string& path) { const char* cpath = path.c_str(); if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { return OK; } - PLOG(WARNING) << "Failed to unmount " << path << "; sending SIGTERM"; - Process::killProcessesWithOpenFiles(cpath, SIGTERM); + PLOG(WARNING) << "Failed to unmount " << path; + sleep(5); + Process::killProcessesWithOpenFiles(cpath, SIGTERM); if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { return OK; } - PLOG(WARNING) << "Failed to unmount " << path << "; sending SIGKILL"; - Process::killProcessesWithOpenFiles(cpath, SIGKILL); + PLOG(WARNING) << "Failed to unmount " << path; + sleep(5); + Process::killProcessesWithOpenFiles(cpath, SIGKILL); if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { return OK; } - PLOG(ERROR) << "Failed to unmount " << path << "; giving up"; + PLOG(ERROR) << "Failed to unmount " << path; + return -errno; } diff --git a/Utils.h b/Utils.h index 9e366e6..a6e1747 100644 --- a/Utils.h +++ b/Utils.h @@ -43,6 +43,9 @@ extern security_context_t sFsckUntrustedContext; status_t CreateDeviceNode(const std::string& path, dev_t dev); status_t DestroyDeviceNode(const std::string& path); +/* fs_prepare_dir wrapper that creates with SELinux context */ +status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid); + /* Really unmounts the path, killing active processes along the way */ status_t ForceUnmount(const std::string& path);