2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
26 #include <sys/ioctl.h>
27 #include <sys/mount.h>
29 #include <sys/types.h>
30 #include <sys/sysmacros.h>
34 #include <linux/kdev_t.h>
36 #include <android-base/logging.h>
37 #include <android-base/parseint.h>
38 #include <android-base/properties.h>
39 #include <android-base/stringprintf.h>
40 #include <android-base/strings.h>
42 #include <cutils/fs.h>
43 #include <utils/Trace.h>
45 #include <selinux/android.h>
47 #include <sysutils/NetlinkEvent.h>
49 #include <private/android_filesystem_config.h>
51 #include <ext4_utils/ext4_crypt.h>
53 #include "Devmapper.h"
54 #include "Ext4Crypt.h"
56 #include "NetlinkManager.h"
60 #include "VolumeManager.h"
64 #include "model/EmulatedVolume.h"
65 #include "model/ObbVolume.h"
67 using android::base::StringPrintf;
68 using android::base::unique_fd;
70 static const char* kPathUserMount = "/mnt/user";
71 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
73 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
75 /* 512MiB is large enough for testing purposes */
76 static const unsigned int kSizeVirtualDisk = 536870912;
78 static const unsigned int kMajorBlockMmc = 179;
79 static const unsigned int kMajorBlockExperimentalMin = 240;
80 static const unsigned int kMajorBlockExperimentalMax = 254;
82 VolumeManager *VolumeManager::sInstance = NULL;
84 VolumeManager *VolumeManager::Instance() {
86 sInstance = new VolumeManager();
90 VolumeManager::VolumeManager() {
93 // For security reasons, assume that a secure keyguard is
94 // showing until we hear otherwise
95 mSecureKeyguardShowing = true;
98 VolumeManager::~VolumeManager() {
101 int VolumeManager::updateVirtualDisk() {
102 ATRACE_NAME("VolumeManager::updateVirtualDisk");
103 if (android::base::GetBoolProperty(kPropVirtualDisk, false)) {
104 if (access(kPathVirtualDisk, F_OK) != 0) {
105 Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
108 if (mVirtualDisk == nullptr) {
109 if (Loop::create(kPathVirtualDisk, mVirtualDiskPath) != 0) {
110 LOG(ERROR) << "Failed to create virtual disk";
115 if (stat(mVirtualDiskPath.c_str(), &buf) < 0) {
116 PLOG(ERROR) << "Failed to stat " << mVirtualDiskPath;
120 auto disk = new android::vold::Disk("virtual", buf.st_rdev, "virtual",
121 android::vold::Disk::Flags::kAdoptable | android::vold::Disk::Flags::kSd);
122 mVirtualDisk = std::shared_ptr<android::vold::Disk>(disk);
123 handleDiskAdded(mVirtualDisk);
126 if (mVirtualDisk != nullptr) {
127 dev_t device = mVirtualDisk->getDevice();
128 handleDiskRemoved(device);
130 Loop::destroyByDevice(mVirtualDiskPath.c_str());
131 mVirtualDisk = nullptr;
134 if (access(kPathVirtualDisk, F_OK) == 0) {
135 unlink(kPathVirtualDisk);
141 int VolumeManager::setDebug(bool enable) {
146 int VolumeManager::start() {
147 ATRACE_NAME("VolumeManager::start");
149 // Always start from a clean slate by unmounting everything in
150 // directories that we own, in case we crashed.
153 Devmapper::destroyAll();
156 // Assume that we always have an emulated volume on internal
157 // storage; the framework will decide if it should be mounted.
158 CHECK(mInternalEmulated == nullptr);
159 mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(
160 new android::vold::EmulatedVolume("/data/media"));
161 mInternalEmulated->create();
163 // Consider creating a virtual disk
169 int VolumeManager::stop() {
170 CHECK(mInternalEmulated != nullptr);
171 mInternalEmulated->destroy();
172 mInternalEmulated = nullptr;
176 void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
177 std::lock_guard<std::mutex> lock(mLock);
180 LOG(VERBOSE) << "----------------";
181 LOG(VERBOSE) << "handleBlockEvent with action " << (int) evt->getAction();
185 std::string eventPath(evt->findParam("DEVPATH")?evt->findParam("DEVPATH"):"");
186 std::string devType(evt->findParam("DEVTYPE")?evt->findParam("DEVTYPE"):"");
188 if (devType != "disk") return;
190 int major = std::stoi(evt->findParam("MAJOR"));
191 int minor = std::stoi(evt->findParam("MINOR"));
192 dev_t device = makedev(major, minor);
194 switch (evt->getAction()) {
195 case NetlinkEvent::Action::kAdd: {
196 for (const auto& source : mDiskSources) {
197 if (source->matches(eventPath)) {
198 // For now, assume that MMC and virtio-blk (the latter is
199 // emulator-specific; see Disk.cpp for details) devices are SD,
200 // and that everything else is USB
201 int flags = source->getFlags();
202 if (major == kMajorBlockMmc
203 || (android::vold::IsRunningInEmulator()
204 && major >= (int) kMajorBlockExperimentalMin
205 && major <= (int) kMajorBlockExperimentalMax)) {
206 flags |= android::vold::Disk::Flags::kSd;
208 flags |= android::vold::Disk::Flags::kUsb;
211 auto disk = new android::vold::Disk(eventPath, device,
212 source->getNickname(), flags);
213 handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk));
219 case NetlinkEvent::Action::kChange: {
220 LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
221 handleDiskChanged(device);
224 case NetlinkEvent::Action::kRemove: {
225 handleDiskRemoved(device);
229 LOG(WARNING) << "Unexpected block event action " << (int) evt->getAction();
235 void VolumeManager::handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk) {
236 // For security reasons, if secure keyguard is showing, wait
237 // until the user unlocks the device to actually touch it
238 if (mSecureKeyguardShowing) {
239 LOG(INFO) << "Found disk at " << disk->getEventPath()
240 << " but delaying scan due to secure keyguard";
241 mPendingDisks.push_back(disk);
244 mDisks.push_back(disk);
248 void VolumeManager::handleDiskChanged(dev_t device) {
249 for (const auto& disk : mDisks) {
250 if (disk->getDevice() == device) {
251 disk->readMetadata();
252 disk->readPartitions();
256 // For security reasons, we ignore all pending disks, since
257 // we'll scan them once the device is unlocked
260 void VolumeManager::handleDiskRemoved(dev_t device) {
261 auto i = mDisks.begin();
262 while (i != mDisks.end()) {
263 if ((*i)->getDevice() == device) {
270 auto j = mPendingDisks.begin();
271 while (j != mPendingDisks.end()) {
272 if ((*j)->getDevice() == device) {
273 j = mPendingDisks.erase(j);
280 void VolumeManager::addDiskSource(const std::shared_ptr<DiskSource>& diskSource) {
281 std::lock_guard<std::mutex> lock(mLock);
282 mDiskSources.push_back(diskSource);
285 std::shared_ptr<android::vold::Disk> VolumeManager::findDisk(const std::string& id) {
286 for (auto disk : mDisks) {
287 if (disk->getId() == id) {
294 std::shared_ptr<android::vold::VolumeBase> VolumeManager::findVolume(const std::string& id) {
295 // Vold could receive "mount" after "shutdown" command in the extreme case.
296 // If this happens, mInternalEmulated will equal nullptr and
297 // we need to deal with it in order to avoid null pointer crash.
298 if (mInternalEmulated != nullptr && mInternalEmulated->getId() == id) {
299 return mInternalEmulated;
301 for (const auto& disk : mDisks) {
302 auto vol = disk->findVolume(id);
303 if (vol != nullptr) {
307 for (const auto& vol : mObbVolumes) {
308 if (vol->getId() == id) {
315 void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
316 std::list<std::string>& list) {
318 for (const auto& disk : mDisks) {
319 disk->listVolumes(type, list);
323 int VolumeManager::forgetPartition(const std::string& partGuid, const std::string& fsUuid) {
324 std::string normalizedGuid;
325 if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
326 LOG(WARNING) << "Invalid GUID " << partGuid;
331 std::string keyPath = android::vold::BuildKeyPath(normalizedGuid);
332 if (unlink(keyPath.c_str()) != 0) {
333 LOG(ERROR) << "Failed to unlink " << keyPath;
336 if (e4crypt_is_native()) {
337 if (!e4crypt_destroy_volume_keys(fsUuid)) {
341 return success ? 0 : -1;
344 int VolumeManager::linkPrimary(userid_t userId) {
345 std::string source(mPrimary->getPath());
346 if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
347 source = StringPrintf("%s/%d", source.c_str(), userId);
348 fs_prepare_dir(source.c_str(), 0755, AID_ROOT, AID_ROOT);
351 std::string target(StringPrintf("/mnt/user/%d/primary", userId));
352 if (TEMP_FAILURE_RETRY(unlink(target.c_str()))) {
353 if (errno != ENOENT) {
354 PLOG(WARNING) << "Failed to unlink " << target;
357 LOG(DEBUG) << "Linking " << source << " to " << target;
358 if (TEMP_FAILURE_RETRY(symlink(source.c_str(), target.c_str()))) {
359 PLOG(WARNING) << "Failed to link";
365 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
366 mAddedUsers[userId] = userSerialNumber;
370 int VolumeManager::onUserRemoved(userid_t userId) {
371 mAddedUsers.erase(userId);
375 int VolumeManager::onUserStarted(userid_t userId) {
376 // Note that sometimes the system will spin up processes from Zygote
377 // before actually starting the user, so we're okay if Zygote
378 // already created this directory.
379 std::string path(StringPrintf("%s/%d", kPathUserMount, userId));
380 fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
382 mStartedUsers.insert(userId);
389 int VolumeManager::onUserStopped(userid_t userId) {
390 mStartedUsers.erase(userId);
394 int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) {
395 mSecureKeyguardShowing = isShowing;
396 if (!mSecureKeyguardShowing) {
397 // Now that secure keyguard has been dismissed, process
399 for (const auto& disk : mPendingDisks) {
401 mDisks.push_back(disk);
403 mPendingDisks.clear();
408 int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
410 for (userid_t userId : mStartedUsers) {
416 static int unmount_tree(const std::string& prefix) {
417 FILE* fp = setmntent("/proc/mounts", "r");
419 PLOG(ERROR) << "Failed to open /proc/mounts";
423 // Some volumes can be stacked on each other, so force unmount in
424 // reverse order to give us the best chance of success.
425 std::list<std::string> toUnmount;
427 while ((mentry = getmntent(fp)) != NULL) {
428 auto test = std::string(mentry->mnt_dir) + "/";
429 if (android::base::StartsWith(test, prefix)) {
430 toUnmount.push_front(test);
435 for (const auto& path : toUnmount) {
436 if (umount2(path.c_str(), MNT_DETACH)) {
437 PLOG(ERROR) << "Failed to unmount " << path;
443 int VolumeManager::remountUid(uid_t uid, const std::string& mode) {
444 LOG(DEBUG) << "Remounting " << uid << " as mode " << mode;
448 std::string rootName;
455 if (!(dir = opendir("/proc"))) {
456 PLOG(ERROR) << "Failed to opendir";
460 // Figure out root namespace to compare against below
461 if (!android::vold::Readlinkat(dirfd(dir), "1/ns/mnt", &rootName)) {
462 PLOG(ERROR) << "Failed to read root namespace";
467 // Poke through all running PIDs look for apps running as UID
468 while ((de = readdir(dir))) {
470 if (de->d_type != DT_DIR) continue;
471 if (!android::base::ParseInt(de->d_name, &pid)) continue;
476 pidFd = openat(dirfd(dir), de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
480 if (fstat(pidFd, &sb) != 0) {
481 PLOG(WARNING) << "Failed to stat " << de->d_name;
484 if (sb.st_uid != uid) {
488 // Matches so far, but refuse to touch if in root namespace
489 LOG(DEBUG) << "Found matching PID " << de->d_name;
490 if (!android::vold::Readlinkat(pidFd, "ns/mnt", &pidName)) {
491 PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
494 if (rootName == pidName) {
495 LOG(WARNING) << "Skipping due to root namespace";
499 // We purposefully leave the namespace open across the fork
500 nsFd = openat(pidFd, "ns/mnt", O_RDONLY); // not O_CLOEXEC
502 PLOG(WARNING) << "Failed to open namespace for " << de->d_name;
506 if (!(child = fork())) {
507 if (setns(nsFd, CLONE_NEWNS) != 0) {
508 PLOG(ERROR) << "Failed to setns for " << de->d_name;
512 unmount_tree("/storage/");
514 std::string storageSource;
515 if (mode == "default") {
516 storageSource = "/mnt/runtime/default";
517 } else if (mode == "read") {
518 storageSource = "/mnt/runtime/read";
519 } else if (mode == "write") {
520 storageSource = "/mnt/runtime/write";
522 // Sane default of no storage visible
525 if (TEMP_FAILURE_RETRY(mount(storageSource.c_str(), "/storage",
526 NULL, MS_BIND | MS_REC, NULL)) == -1) {
527 PLOG(ERROR) << "Failed to mount " << storageSource << " for "
531 if (TEMP_FAILURE_RETRY(mount(NULL, "/storage", NULL,
532 MS_REC | MS_SLAVE, NULL)) == -1) {
533 PLOG(ERROR) << "Failed to set MS_SLAVE to /storage for "
538 // Mount user-specific symlink helper into place
539 userid_t user_id = multiuser_get_user_id(uid);
540 std::string userSource(StringPrintf("/mnt/user/%d", user_id));
541 if (TEMP_FAILURE_RETRY(mount(userSource.c_str(), "/storage/self",
542 NULL, MS_BIND, NULL)) == -1) {
543 PLOG(ERROR) << "Failed to mount " << userSource << " for "
552 PLOG(ERROR) << "Failed to fork";
555 TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
566 int VolumeManager::reset() {
567 // Tear down all existing disks/volumes and start from a blank slate so
568 // newly connected framework hears all events.
569 if (mInternalEmulated != nullptr) {
570 mInternalEmulated->destroy();
571 mInternalEmulated->create();
573 for (const auto& disk : mDisks) {
579 mStartedUsers.clear();
583 // Can be called twice (sequentially) during shutdown. should be safe for that.
584 int VolumeManager::shutdown() {
585 if (mInternalEmulated == nullptr) {
586 return 0; // already shutdown
588 android::vold::sSleepOnUnmount = false;
589 mInternalEmulated->destroy();
590 mInternalEmulated = nullptr;
591 for (const auto& disk : mDisks) {
595 mPendingDisks.clear();
596 android::vold::sSleepOnUnmount = true;
600 int VolumeManager::unmountAll() {
601 std::lock_guard<std::mutex> lock(mLock);
602 ATRACE_NAME("VolumeManager::unmountAll()");
604 // First, try gracefully unmounting all known devices
605 if (mInternalEmulated != nullptr) {
606 mInternalEmulated->unmount();
608 for (const auto& disk : mDisks) {
612 // Worst case we might have some stale mounts lurking around, so
613 // force unmount those just to be safe.
614 FILE* fp = setmntent("/proc/mounts", "r");
616 PLOG(ERROR) << "Failed to open /proc/mounts";
620 // Some volumes can be stacked on each other, so force unmount in
621 // reverse order to give us the best chance of success.
622 std::list<std::string> toUnmount;
624 while ((mentry = getmntent(fp)) != NULL) {
625 auto test = std::string(mentry->mnt_dir);
626 if ((android::base::StartsWith(test, "/mnt/") &&
627 !android::base::StartsWith(test, "/mnt/vendor")) ||
628 android::base::StartsWith(test, "/storage/")) {
629 toUnmount.push_front(test);
634 for (const auto& path : toUnmount) {
635 LOG(DEBUG) << "Tearing down stale mount " << path;
636 android::vold::ForceUnmount(path);
642 int VolumeManager::mkdirs(const std::string& path) {
643 // Only offer to create directories for paths managed by vold
644 if (android::base::StartsWith(path, "/storage/")) {
645 // fs_mkdirs() does symlink checking and relative path enforcement
646 return fs_mkdirs(path.c_str(), 0700);
648 LOG(ERROR) << "Failed to find mounted volume for " << path;
653 static size_t kAppFuseMaxMountPointName = 32;
655 static android::status_t getMountPath(uid_t uid, const std::string& name, std::string* path) {
656 if (name.size() > kAppFuseMaxMountPointName) {
657 LOG(ERROR) << "AppFuse mount name is too long.";
660 for (size_t i = 0; i < name.size(); i++) {
661 if (!isalnum(name[i])) {
662 LOG(ERROR) << "AppFuse mount name contains invalid character.";
666 *path = android::base::StringPrintf("/mnt/appfuse/%d_%s", uid, name.c_str());
670 static android::status_t mountInNamespace(uid_t uid, int device_fd, const std::string& path) {
671 // Remove existing mount.
672 android::vold::ForceUnmount(path);
674 const auto opts = android::base::StringPrintf(
677 "default_permissions,"
679 "user_id=%d,group_id=%d,"
680 "context=\"u:object_r:app_fuse_file:s0\","
681 "fscontext=u:object_r:app_fusefs:s0",
686 const int result = TEMP_FAILURE_RETRY(mount(
687 "/dev/fuse", path.c_str(), "fuse",
688 MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()));
690 PLOG(ERROR) << "Failed to mount " << path;
697 static android::status_t runCommandInNamespace(const std::string& command,
700 const std::string& path,
703 LOG(DEBUG) << "Run app fuse command " << command << " for the path " << path
704 << " in namespace " << uid;
707 unique_fd dir(open("/proc", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
708 if (dir.get() == -1) {
709 PLOG(ERROR) << "Failed to open /proc";
713 // Obtains process file descriptor.
714 const std::string pid_str = android::base::StringPrintf("%d", pid);
715 const unique_fd pid_fd(
716 openat(dir.get(), pid_str.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
717 if (pid_fd.get() == -1) {
718 PLOG(ERROR) << "Failed to open /proc/" << pid;
722 // Check UID of process.
725 const int result = fstat(pid_fd.get(), &sb);
727 PLOG(ERROR) << "Failed to stat /proc/" << pid;
730 if (sb.st_uid != AID_SYSTEM) {
731 LOG(ERROR) << "Only system can mount appfuse. UID expected=" << AID_SYSTEM
732 << ", actual=" << sb.st_uid;
737 // Matches so far, but refuse to touch if in root namespace
739 std::string rootName;
741 if (!android::vold::Readlinkat(dir.get(), "1/ns/mnt", &rootName)
742 || !android::vold::Readlinkat(pid_fd.get(), "ns/mnt", &pidName)) {
743 PLOG(ERROR) << "Failed to read namespaces";
746 if (rootName == pidName) {
747 LOG(ERROR) << "Don't mount appfuse in root namespace";
752 // We purposefully leave the namespace open across the fork
753 unique_fd ns_fd(openat(pid_fd.get(), "ns/mnt", O_RDONLY)); // not O_CLOEXEC
754 if (ns_fd.get() < 0) {
755 PLOG(ERROR) << "Failed to open namespace for /proc/" << pid << "/ns/mnt";
761 if (setns(ns_fd.get(), CLONE_NEWNS) != 0) {
762 PLOG(ERROR) << "Failed to setns";
766 if (command == "mount") {
767 _exit(mountInNamespace(uid, device_fd, path));
768 } else if (command == "unmount") {
769 // If it's just after all FD opened on mount point are closed, umount2 can fail with
770 // EBUSY. To avoid the case, specify MNT_DETACH.
771 if (umount2(path.c_str(), UMOUNT_NOFOLLOW | MNT_DETACH) != 0 &&
772 errno != EINVAL && errno != ENOENT) {
773 PLOG(ERROR) << "Failed to unmount directory.";
776 if (rmdir(path.c_str()) != 0) {
777 PLOG(ERROR) << "Failed to remove the mount directory.";
782 LOG(ERROR) << "Unknown appfuse command " << command;
788 PLOG(ERROR) << "Failed to folk child process";
792 android::status_t status;
793 TEMP_FAILURE_RETRY(waitpid(child, &status, 0));
798 int VolumeManager::createObb(const std::string& sourcePath, const std::string& sourceKey,
799 int32_t ownerGid, std::string* outVolId) {
800 int id = mNextObbId++;
802 auto vol = std::shared_ptr<android::vold::VolumeBase>(
803 new android::vold::ObbVolume(id, sourcePath, sourceKey, ownerGid));
806 mObbVolumes.push_back(vol);
807 *outVolId = vol->getId();
811 int VolumeManager::destroyObb(const std::string& volId) {
812 auto i = mObbVolumes.begin();
813 while (i != mObbVolumes.end()) {
814 if ((*i)->getId() == volId) {
816 i = mObbVolumes.erase(i);
824 int VolumeManager::mountAppFuse(uid_t uid, pid_t pid, int mountId,
825 android::base::unique_fd* device_fd) {
826 std::string name = std::to_string(mountId);
828 // Check mount point name.
830 if (getMountPath(uid, name, &path) != android::OK) {
831 LOG(ERROR) << "Invalid mount point name";
835 // Create directories.
836 const android::status_t result = android::vold::PrepareDir(path, 0700, 0, 0);
837 if (result != android::OK) {
838 PLOG(ERROR) << "Failed to prepare directory " << path;
843 device_fd->reset(open("/dev/fuse", O_RDWR)); // not O_CLOEXEC
844 if (device_fd->get() == -1) {
845 PLOG(ERROR) << "Failed to open /dev/fuse";
850 return runCommandInNamespace("mount", uid, pid, path, device_fd->get());
853 int VolumeManager::unmountAppFuse(uid_t uid, pid_t pid, int mountId) {
854 std::string name = std::to_string(mountId);
856 // Check mount point name.
858 if (getMountPath(uid, name, &path) != android::OK) {
859 LOG(ERROR) << "Invalid mount point name";
863 return runCommandInNamespace("unmount", uid, pid, path, -1 /* device_fd */);