1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
18 
19 #include <dirent.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <mntent.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/ioctl.h>
27 #include <sys/mount.h>
28 #include <sys/stat.h>
29 #include <sys/sysmacros.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
33 #include <array>
34 
35 #include <linux/kdev_t.h>
36 
37 #include <ApexProperties.sysprop.h>
38 #include <android-base/logging.h>
39 #include <android-base/parseint.h>
40 #include <android-base/properties.h>
41 #include <android-base/stringprintf.h>
42 #include <android-base/strings.h>
43 
44 #include <cutils/fs.h>
45 #include <utils/Trace.h>
46 
47 #include <selinux/android.h>
48 
49 #include <sysutils/NetlinkEvent.h>
50 
51 #include <private/android_filesystem_config.h>
52 
53 #include <fscrypt/fscrypt.h>
54 
55 #include "AppFuseUtil.h"
56 #include "Devmapper.h"
57 #include "FsCrypt.h"
58 #include "Loop.h"
59 #include "NetlinkManager.h"
60 #include "Process.h"
61 #include "Utils.h"
62 #include "VoldNativeService.h"
63 #include "VoldUtil.h"
64 #include "VolumeManager.h"
65 #include "fs/Ext4.h"
66 #include "fs/Vfat.h"
67 #include "model/EmulatedVolume.h"
68 #include "model/ObbVolume.h"
69 #include "model/StubVolume.h"
70 
71 using android::OK;
72 using android::base::GetBoolProperty;
73 using android::base::StartsWith;
74 using android::base::StringAppendF;
75 using android::base::StringPrintf;
76 using android::base::unique_fd;
77 using android::vold::BindMount;
78 using android::vold::CreateDir;
79 using android::vold::DeleteDirContents;
80 using android::vold::DeleteDirContentsAndDir;
81 using android::vold::IsVirtioBlkDevice;
82 using android::vold::Symlink;
83 using android::vold::Unlink;
84 using android::vold::UnmountTree;
85 using android::vold::VoldNativeService;
86 
87 static const char* kPathUserMount = "/mnt/user";
88 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
89 
90 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
91 
92 static const std::string kEmptyString("");
93 
94 /* 512MiB is large enough for testing purposes */
95 static const unsigned int kSizeVirtualDisk = 536870912;
96 
97 static const unsigned int kMajorBlockMmc = 179;
98 
99 VolumeManager* VolumeManager::sInstance = NULL;
100 
Instance()101 VolumeManager* VolumeManager::Instance() {
102     if (!sInstance) sInstance = new VolumeManager();
103     return sInstance;
104 }
105 
VolumeManager()106 VolumeManager::VolumeManager() {
107     mDebug = false;
108     mNextObbId = 0;
109     mNextStubVolumeId = 0;
110     // For security reasons, assume that a secure keyguard is
111     // showing until we hear otherwise
112     mSecureKeyguardShowing = true;
113 }
114 
~VolumeManager()115 VolumeManager::~VolumeManager() {}
116 
updateVirtualDisk()117 int VolumeManager::updateVirtualDisk() {
118     ATRACE_NAME("VolumeManager::updateVirtualDisk");
119     if (GetBoolProperty(kPropVirtualDisk, false)) {
120         if (access(kPathVirtualDisk, F_OK) != 0) {
121             Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
122         }
123 
124         if (mVirtualDisk == nullptr) {
125             if (Loop::create(kPathVirtualDisk, mVirtualDiskPath) != 0) {
126                 LOG(ERROR) << "Failed to create virtual disk";
127                 return -1;
128             }
129 
130             struct stat buf;
131             if (stat(mVirtualDiskPath.c_str(), &buf) < 0) {
132                 PLOG(ERROR) << "Failed to stat " << mVirtualDiskPath;
133                 return -1;
134             }
135 
136             auto disk = new android::vold::Disk(
137                 "virtual", buf.st_rdev, "virtual",
138                 android::vold::Disk::Flags::kAdoptable | android::vold::Disk::Flags::kSd);
139             mVirtualDisk = std::shared_ptr<android::vold::Disk>(disk);
140             handleDiskAdded(mVirtualDisk);
141         }
142     } else {
143         if (mVirtualDisk != nullptr) {
144             dev_t device = mVirtualDisk->getDevice();
145             handleDiskRemoved(device);
146 
147             Loop::destroyByDevice(mVirtualDiskPath.c_str());
148             mVirtualDisk = nullptr;
149         }
150 
151         if (access(kPathVirtualDisk, F_OK) == 0) {
152             unlink(kPathVirtualDisk);
153         }
154     }
155     return 0;
156 }
157 
setDebug(bool enable)158 int VolumeManager::setDebug(bool enable) {
159     mDebug = enable;
160     return 0;
161 }
162 
start()163 int VolumeManager::start() {
164     ATRACE_NAME("VolumeManager::start");
165 
166     // Always start from a clean slate by unmounting everything in
167     // directories that we own, in case we crashed.
168     unmountAll();
169 
170     Devmapper::destroyAll();
171     Loop::destroyAll();
172 
173     // Assume that we always have an emulated volume on internal
174     // storage; the framework will decide if it should be mounted.
175     CHECK(mInternalEmulated == nullptr);
176     mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(
177         new android::vold::EmulatedVolume("/data/media"));
178     mInternalEmulated->create();
179 
180     // Consider creating a virtual disk
181     updateVirtualDisk();
182 
183     return 0;
184 }
185 
stop()186 int VolumeManager::stop() {
187     CHECK(mInternalEmulated != nullptr);
188     mInternalEmulated->destroy();
189     mInternalEmulated = nullptr;
190     return 0;
191 }
192 
handleBlockEvent(NetlinkEvent * evt)193 void VolumeManager::handleBlockEvent(NetlinkEvent* evt) {
194     std::lock_guard<std::mutex> lock(mLock);
195 
196     if (mDebug) {
197         LOG(DEBUG) << "----------------";
198         LOG(DEBUG) << "handleBlockEvent with action " << (int)evt->getAction();
199         evt->dump();
200     }
201 
202     std::string eventPath(evt->findParam("DEVPATH") ? evt->findParam("DEVPATH") : "");
203     std::string devType(evt->findParam("DEVTYPE") ? evt->findParam("DEVTYPE") : "");
204 
205     if (devType != "disk") return;
206 
207     int major = std::stoi(evt->findParam("MAJOR"));
208     int minor = std::stoi(evt->findParam("MINOR"));
209     dev_t device = makedev(major, minor);
210 
211     switch (evt->getAction()) {
212         case NetlinkEvent::Action::kAdd: {
213             for (const auto& source : mDiskSources) {
214                 if (source->matches(eventPath)) {
215                     // For now, assume that MMC and virtio-blk (the latter is
216                     // specific to virtual platforms; see Utils.cpp for details)
217                     // devices are SD, and that everything else is USB
218                     int flags = source->getFlags();
219                     if (major == kMajorBlockMmc || IsVirtioBlkDevice(major)) {
220                         flags |= android::vold::Disk::Flags::kSd;
221                     } else {
222                         flags |= android::vold::Disk::Flags::kUsb;
223                     }
224 
225                     auto disk =
226                         new android::vold::Disk(eventPath, device, source->getNickname(), flags);
227                     handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk));
228                     break;
229                 }
230             }
231             break;
232         }
233         case NetlinkEvent::Action::kChange: {
234             LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
235             handleDiskChanged(device);
236             break;
237         }
238         case NetlinkEvent::Action::kRemove: {
239             handleDiskRemoved(device);
240             break;
241         }
242         default: {
243             LOG(WARNING) << "Unexpected block event action " << (int)evt->getAction();
244             break;
245         }
246     }
247 }
248 
handleDiskAdded(const std::shared_ptr<android::vold::Disk> & disk)249 void VolumeManager::handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk) {
250     // For security reasons, if secure keyguard is showing, wait
251     // until the user unlocks the device to actually touch it
252     if (mSecureKeyguardShowing) {
253         LOG(INFO) << "Found disk at " << disk->getEventPath()
254                   << " but delaying scan due to secure keyguard";
255         mPendingDisks.push_back(disk);
256     } else {
257         disk->create();
258         mDisks.push_back(disk);
259     }
260 }
261 
handleDiskChanged(dev_t device)262 void VolumeManager::handleDiskChanged(dev_t device) {
263     for (const auto& disk : mDisks) {
264         if (disk->getDevice() == device) {
265             disk->readMetadata();
266             disk->readPartitions();
267         }
268     }
269 
270     // For security reasons, we ignore all pending disks, since
271     // we'll scan them once the device is unlocked
272 }
273 
handleDiskRemoved(dev_t device)274 void VolumeManager::handleDiskRemoved(dev_t device) {
275     auto i = mDisks.begin();
276     while (i != mDisks.end()) {
277         if ((*i)->getDevice() == device) {
278             (*i)->destroy();
279             i = mDisks.erase(i);
280         } else {
281             ++i;
282         }
283     }
284     auto j = mPendingDisks.begin();
285     while (j != mPendingDisks.end()) {
286         if ((*j)->getDevice() == device) {
287             j = mPendingDisks.erase(j);
288         } else {
289             ++j;
290         }
291     }
292 }
293 
addDiskSource(const std::shared_ptr<DiskSource> & diskSource)294 void VolumeManager::addDiskSource(const std::shared_ptr<DiskSource>& diskSource) {
295     std::lock_guard<std::mutex> lock(mLock);
296     mDiskSources.push_back(diskSource);
297 }
298 
findDisk(const std::string & id)299 std::shared_ptr<android::vold::Disk> VolumeManager::findDisk(const std::string& id) {
300     for (auto disk : mDisks) {
301         if (disk->getId() == id) {
302             return disk;
303         }
304     }
305     return nullptr;
306 }
307 
findVolume(const std::string & id)308 std::shared_ptr<android::vold::VolumeBase> VolumeManager::findVolume(const std::string& id) {
309     // Vold could receive "mount" after "shutdown" command in the extreme case.
310     // If this happens, mInternalEmulated will equal nullptr and
311     // we need to deal with it in order to avoid null pointer crash.
312     if (mInternalEmulated != nullptr && mInternalEmulated->getId() == id) {
313         return mInternalEmulated;
314     }
315     for (const auto& disk : mDisks) {
316         auto vol = disk->findVolume(id);
317         if (vol != nullptr) {
318             return vol;
319         }
320     }
321     for (const auto& vol : mStubVolumes) {
322         if (vol->getId() == id) {
323             return vol;
324         }
325     }
326     for (const auto& vol : mObbVolumes) {
327         if (vol->getId() == id) {
328             return vol;
329         }
330     }
331     return nullptr;
332 }
333 
listVolumes(android::vold::VolumeBase::Type type,std::list<std::string> & list) const334 void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
335                                 std::list<std::string>& list) const {
336     list.clear();
337     for (const auto& disk : mDisks) {
338         disk->listVolumes(type, list);
339     }
340 }
341 
forgetPartition(const std::string & partGuid,const std::string & fsUuid)342 int VolumeManager::forgetPartition(const std::string& partGuid, const std::string& fsUuid) {
343     std::string normalizedGuid;
344     if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
345         LOG(WARNING) << "Invalid GUID " << partGuid;
346         return -1;
347     }
348 
349     bool success = true;
350     std::string keyPath = android::vold::BuildKeyPath(normalizedGuid);
351     if (unlink(keyPath.c_str()) != 0) {
352         LOG(ERROR) << "Failed to unlink " << keyPath;
353         success = false;
354     }
355     if (fscrypt_is_native()) {
356         if (!fscrypt_destroy_volume_keys(fsUuid)) {
357             success = false;
358         }
359     }
360     return success ? 0 : -1;
361 }
362 
linkPrimary(userid_t userId)363 int VolumeManager::linkPrimary(userid_t userId) {
364     std::string source(mPrimary->getPath());
365     if (mPrimary->isEmulated()) {
366         source = StringPrintf("%s/%d", source.c_str(), userId);
367         fs_prepare_dir(source.c_str(), 0755, AID_ROOT, AID_ROOT);
368     }
369 
370     std::string target(StringPrintf("/mnt/user/%d/primary", userId));
371     LOG(DEBUG) << "Linking " << source << " to " << target;
372     Symlink(source, target);
373     return 0;
374 }
375 
onUserAdded(userid_t userId,int userSerialNumber)376 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
377     mAddedUsers[userId] = userSerialNumber;
378     return 0;
379 }
380 
onUserRemoved(userid_t userId)381 int VolumeManager::onUserRemoved(userid_t userId) {
382     mAddedUsers.erase(userId);
383     return 0;
384 }
385 
onUserStarted(userid_t userId)386 int VolumeManager::onUserStarted(userid_t userId) {
387     LOG(VERBOSE) << "onUserStarted: " << userId;
388     // Note that sometimes the system will spin up processes from Zygote
389     // before actually starting the user, so we're okay if Zygote
390     // already created this directory.
391     std::string path(StringPrintf("%s/%d", kPathUserMount, userId));
392     fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
393 
394     mStartedUsers.insert(userId);
395     if (mPrimary) {
396         linkPrimary(userId);
397     }
398     return 0;
399 }
400 
onUserStopped(userid_t userId)401 int VolumeManager::onUserStopped(userid_t userId) {
402     LOG(VERBOSE) << "onUserStopped: " << userId;
403     mStartedUsers.erase(userId);
404     return 0;
405 }
406 
onSecureKeyguardStateChanged(bool isShowing)407 int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) {
408     mSecureKeyguardShowing = isShowing;
409     if (!mSecureKeyguardShowing) {
410         // Now that secure keyguard has been dismissed, process
411         // any pending disks
412         for (const auto& disk : mPendingDisks) {
413             disk->create();
414             mDisks.push_back(disk);
415         }
416         mPendingDisks.clear();
417     }
418     return 0;
419 }
420 
setPrimary(const std::shared_ptr<android::vold::VolumeBase> & vol)421 int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
422     mPrimary = vol;
423     for (userid_t userId : mStartedUsers) {
424         linkPrimary(userId);
425     }
426     return 0;
427 }
428 
remountUid(uid_t uid,int32_t mountMode)429 int VolumeManager::remountUid(uid_t uid, int32_t mountMode) {
430     std::string mode;
431     switch (mountMode) {
432         case VoldNativeService::REMOUNT_MODE_NONE:
433             mode = "none";
434             break;
435         case VoldNativeService::REMOUNT_MODE_DEFAULT:
436             mode = "default";
437             break;
438         case VoldNativeService::REMOUNT_MODE_READ:
439             mode = "read";
440             break;
441         case VoldNativeService::REMOUNT_MODE_WRITE:
442         case VoldNativeService::REMOUNT_MODE_LEGACY:
443         case VoldNativeService::REMOUNT_MODE_INSTALLER:
444             mode = "write";
445             break;
446         case VoldNativeService::REMOUNT_MODE_FULL:
447             mode = "full";
448             break;
449         default:
450             PLOG(ERROR) << "Unknown mode " << std::to_string(mountMode);
451             return -1;
452     }
453     LOG(DEBUG) << "Remounting " << uid << " as mode " << mode;
454 
455     DIR* dir;
456     struct dirent* de;
457     std::string rootName;
458     std::string pidName;
459     int pidFd;
460     int nsFd;
461     struct stat sb;
462     pid_t child;
463 
464     static bool apexUpdatable = android::sysprop::ApexProperties::updatable().value_or(false);
465 
466     if (!(dir = opendir("/proc"))) {
467         PLOG(ERROR) << "Failed to opendir";
468         return -1;
469     }
470 
471     // Figure out root namespace to compare against below
472     if (!android::vold::Readlinkat(dirfd(dir), "1/ns/mnt", &rootName)) {
473         PLOG(ERROR) << "Failed to read root namespace";
474         closedir(dir);
475         return -1;
476     }
477 
478     // Poke through all running PIDs look for apps running as UID
479     while ((de = readdir(dir))) {
480         pid_t pid;
481         if (de->d_type != DT_DIR) continue;
482         if (!android::base::ParseInt(de->d_name, &pid)) continue;
483 
484         pidFd = -1;
485         nsFd = -1;
486 
487         pidFd = openat(dirfd(dir), de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
488         if (pidFd < 0) {
489             goto next;
490         }
491         if (fstat(pidFd, &sb) != 0) {
492             PLOG(WARNING) << "Failed to stat " << de->d_name;
493             goto next;
494         }
495         if (sb.st_uid != uid) {
496             goto next;
497         }
498 
499         // Matches so far, but refuse to touch if in root namespace
500         LOG(DEBUG) << "Found matching PID " << de->d_name;
501         if (!android::vold::Readlinkat(pidFd, "ns/mnt", &pidName)) {
502             PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
503             goto next;
504         }
505         if (rootName == pidName) {
506             LOG(WARNING) << "Skipping due to root namespace";
507             goto next;
508         }
509 
510         if (apexUpdatable) {
511             std::string exeName;
512             // When ro.apex.bionic_updatable is set to true,
513             // some early native processes have mount namespaces that are different
514             // from that of the init. Therefore, above check can't filter them out.
515             // Since the propagation type of / is 'shared', unmounting /storage
516             // for the early native processes affects other processes including
517             // init. Filter out such processes by skipping if a process is a
518             // non-Java process whose UID is < AID_APP_START. (The UID condition
519             // is required to not filter out child processes spawned by apps.)
520             if (!android::vold::Readlinkat(pidFd, "exe", &exeName)) {
521                 PLOG(WARNING) << "Failed to read exe name for " << de->d_name;
522                 goto next;
523             }
524             if (!StartsWith(exeName, "/system/bin/app_process") && sb.st_uid < AID_APP_START) {
525                 LOG(WARNING) << "Skipping due to native system process";
526                 goto next;
527             }
528         }
529 
530         // We purposefully leave the namespace open across the fork
531         // NOLINTNEXTLINE(android-cloexec-open): Deliberately not O_CLOEXEC
532         nsFd = openat(pidFd, "ns/mnt", O_RDONLY);
533         if (nsFd < 0) {
534             PLOG(WARNING) << "Failed to open namespace for " << de->d_name;
535             goto next;
536         }
537 
538         if (!(child = fork())) {
539             if (setns(nsFd, CLONE_NEWNS) != 0) {
540                 PLOG(ERROR) << "Failed to setns for " << de->d_name;
541                 _exit(1);
542             }
543 
544             android::vold::UnmountTree("/storage/");
545 
546             std::string storageSource;
547             if (mode == "default") {
548                 storageSource = "/mnt/runtime/default";
549             } else if (mode == "read") {
550                 storageSource = "/mnt/runtime/read";
551             } else if (mode == "write") {
552                 storageSource = "/mnt/runtime/write";
553             } else if (mode == "full") {
554                 storageSource = "/mnt/runtime/full";
555             } else {
556                 // Sane default of no storage visible
557                 _exit(0);
558             }
559             if (TEMP_FAILURE_RETRY(
560                     mount(storageSource.c_str(), "/storage", NULL, MS_BIND | MS_REC, NULL)) == -1) {
561                 PLOG(ERROR) << "Failed to mount " << storageSource << " for " << de->d_name;
562                 _exit(1);
563             }
564             if (TEMP_FAILURE_RETRY(mount(NULL, "/storage", NULL, MS_REC | MS_SLAVE, NULL)) == -1) {
565                 PLOG(ERROR) << "Failed to set MS_SLAVE to /storage for " << de->d_name;
566                 _exit(1);
567             }
568 
569             // Mount user-specific symlink helper into place
570             userid_t user_id = multiuser_get_user_id(uid);
571             std::string userSource(StringPrintf("/mnt/user/%d", user_id));
572             if (TEMP_FAILURE_RETRY(
573                     mount(userSource.c_str(), "/storage/self", NULL, MS_BIND, NULL)) == -1) {
574                 PLOG(ERROR) << "Failed to mount " << userSource << " for " << de->d_name;
575                 _exit(1);
576             }
577 
578             _exit(0);
579         }
580 
581         if (child == -1) {
582             PLOG(ERROR) << "Failed to fork";
583             goto next;
584         } else {
585             TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
586         }
587 
588     next:
589         close(nsFd);
590         close(pidFd);
591     }
592     closedir(dir);
593     return 0;
594 }
595 
reset()596 int VolumeManager::reset() {
597     // Tear down all existing disks/volumes and start from a blank slate so
598     // newly connected framework hears all events.
599     if (mInternalEmulated != nullptr) {
600         mInternalEmulated->destroy();
601         mInternalEmulated->create();
602     }
603     for (const auto& disk : mDisks) {
604         disk->destroy();
605         disk->create();
606     }
607     updateVirtualDisk();
608     mAddedUsers.clear();
609     mStartedUsers.clear();
610     return 0;
611 }
612 
613 // Can be called twice (sequentially) during shutdown. should be safe for that.
shutdown()614 int VolumeManager::shutdown() {
615     if (mInternalEmulated == nullptr) {
616         return 0;  // already shutdown
617     }
618     android::vold::sSleepOnUnmount = false;
619     mInternalEmulated->destroy();
620     mInternalEmulated = nullptr;
621     for (const auto& disk : mDisks) {
622         disk->destroy();
623     }
624     mStubVolumes.clear();
625     mDisks.clear();
626     mPendingDisks.clear();
627     android::vold::sSleepOnUnmount = true;
628     return 0;
629 }
630 
unmountAll()631 int VolumeManager::unmountAll() {
632     std::lock_guard<std::mutex> lock(mLock);
633     ATRACE_NAME("VolumeManager::unmountAll()");
634 
635     // First, try gracefully unmounting all known devices
636     if (mInternalEmulated != nullptr) {
637         mInternalEmulated->unmount();
638     }
639     for (const auto& stub : mStubVolumes) {
640         stub->unmount();
641     }
642     for (const auto& disk : mDisks) {
643         disk->unmountAll();
644     }
645 
646     // Worst case we might have some stale mounts lurking around, so
647     // force unmount those just to be safe.
648     FILE* fp = setmntent("/proc/mounts", "re");
649     if (fp == NULL) {
650         PLOG(ERROR) << "Failed to open /proc/mounts";
651         return -errno;
652     }
653 
654     // Some volumes can be stacked on each other, so force unmount in
655     // reverse order to give us the best chance of success.
656     std::list<std::string> toUnmount;
657     mntent* mentry;
658     while ((mentry = getmntent(fp)) != NULL) {
659         auto test = std::string(mentry->mnt_dir);
660         if ((StartsWith(test, "/mnt/") &&
661 #ifdef __ANDROID_DEBUGGABLE__
662              !StartsWith(test, "/mnt/scratch") &&
663 #endif
664              !StartsWith(test, "/mnt/vendor") && !StartsWith(test, "/mnt/product")) ||
665             StartsWith(test, "/storage/")) {
666             toUnmount.push_front(test);
667         }
668     }
669     endmntent(fp);
670 
671     for (const auto& path : toUnmount) {
672         LOG(DEBUG) << "Tearing down stale mount " << path;
673         android::vold::ForceUnmount(path);
674     }
675 
676     return 0;
677 }
678 
mkdirs(const std::string & path)679 int VolumeManager::mkdirs(const std::string& path) {
680     // Only offer to create directories for paths managed by vold
681     if (StartsWith(path, "/storage/")) {
682         // fs_mkdirs() does symlink checking and relative path enforcement
683         return fs_mkdirs(path.c_str(), 0700);
684     } else {
685         LOG(ERROR) << "Failed to find mounted volume for " << path;
686         return -EINVAL;
687     }
688 }
689 
createObb(const std::string & sourcePath,const std::string & sourceKey,int32_t ownerGid,std::string * outVolId)690 int VolumeManager::createObb(const std::string& sourcePath, const std::string& sourceKey,
691                              int32_t ownerGid, std::string* outVolId) {
692     int id = mNextObbId++;
693 
694     auto vol = std::shared_ptr<android::vold::VolumeBase>(
695         new android::vold::ObbVolume(id, sourcePath, sourceKey, ownerGid));
696     vol->create();
697 
698     mObbVolumes.push_back(vol);
699     *outVolId = vol->getId();
700     return android::OK;
701 }
702 
destroyObb(const std::string & volId)703 int VolumeManager::destroyObb(const std::string& volId) {
704     auto i = mObbVolumes.begin();
705     while (i != mObbVolumes.end()) {
706         if ((*i)->getId() == volId) {
707             (*i)->destroy();
708             i = mObbVolumes.erase(i);
709         } else {
710             ++i;
711         }
712     }
713     return android::OK;
714 }
715 
createStubVolume(const std::string & sourcePath,const std::string & mountPath,const std::string & fsType,const std::string & fsUuid,const std::string & fsLabel,std::string * outVolId)716 int VolumeManager::createStubVolume(const std::string& sourcePath, const std::string& mountPath,
717                                     const std::string& fsType, const std::string& fsUuid,
718                                     const std::string& fsLabel, std::string* outVolId) {
719     int id = mNextStubVolumeId++;
720     auto vol = std::shared_ptr<android::vold::VolumeBase>(
721         new android::vold::StubVolume(id, sourcePath, mountPath, fsType, fsUuid, fsLabel));
722     vol->create();
723 
724     mStubVolumes.push_back(vol);
725     *outVolId = vol->getId();
726     return android::OK;
727 }
728 
destroyStubVolume(const std::string & volId)729 int VolumeManager::destroyStubVolume(const std::string& volId) {
730     auto i = mStubVolumes.begin();
731     while (i != mStubVolumes.end()) {
732         if ((*i)->getId() == volId) {
733             (*i)->destroy();
734             i = mStubVolumes.erase(i);
735         } else {
736             ++i;
737         }
738     }
739     return android::OK;
740 }
741 
mountAppFuse(uid_t uid,int mountId,unique_fd * device_fd)742 int VolumeManager::mountAppFuse(uid_t uid, int mountId, unique_fd* device_fd) {
743     return android::vold::MountAppFuse(uid, mountId, device_fd);
744 }
745 
unmountAppFuse(uid_t uid,int mountId)746 int VolumeManager::unmountAppFuse(uid_t uid, int mountId) {
747     return android::vold::UnmountAppFuse(uid, mountId);
748 }
749 
openAppFuseFile(uid_t uid,int mountId,int fileId,int flags)750 int VolumeManager::openAppFuseFile(uid_t uid, int mountId, int fileId, int flags) {
751     return android::vold::OpenAppFuseFile(uid, mountId, fileId, flags);
752 }
753