• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <limits.h>
23 #include <mntent.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/ioctl.h>
28 #include <sys/mount.h>
29 #include <sys/stat.h>
30 #include <sys/sysmacros.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <unistd.h>
34 #include <array>
35 
36 #include <linux/kdev_t.h>
37 
38 #include <ApexProperties.sysprop.h>
39 #include <android-base/logging.h>
40 #include <android-base/parseint.h>
41 #include <android-base/properties.h>
42 #include <android-base/stringprintf.h>
43 #include <android-base/strings.h>
44 #include <async_safe/log.h>
45 
46 #include <cutils/fs.h>
47 #include <utils/Trace.h>
48 
49 #include <selinux/android.h>
50 
51 #include <sysutils/NetlinkEvent.h>
52 
53 #include <private/android_filesystem_config.h>
54 
55 #include <fscrypt/fscrypt.h>
56 
57 #include "AppFuseUtil.h"
58 #include "Devmapper.h"
59 #include "FsCrypt.h"
60 #include "Loop.h"
61 #include "NetlinkManager.h"
62 #include "Process.h"
63 #include "Utils.h"
64 #include "VoldNativeService.h"
65 #include "VoldUtil.h"
66 #include "VolumeManager.h"
67 #include "fs/Ext4.h"
68 #include "fs/Vfat.h"
69 #include "model/EmulatedVolume.h"
70 #include "model/ObbVolume.h"
71 #include "model/PrivateVolume.h"
72 #include "model/StubVolume.h"
73 
74 using android::OK;
75 using android::base::GetBoolProperty;
76 using android::base::StartsWith;
77 using android::base::StringAppendF;
78 using android::base::StringPrintf;
79 using android::base::unique_fd;
80 using android::vold::BindMount;
81 using android::vold::CreateDir;
82 using android::vold::DeleteDirContents;
83 using android::vold::DeleteDirContentsAndDir;
84 using android::vold::EnsureDirExists;
85 using android::vold::IsFilesystemSupported;
86 using android::vold::IsSdcardfsUsed;
87 using android::vold::IsVirtioBlkDevice;
88 using android::vold::PrepareAndroidDirs;
89 using android::vold::PrepareAppDirFromRoot;
90 using android::vold::PrivateVolume;
91 using android::vold::Symlink;
92 using android::vold::Unlink;
93 using android::vold::UnmountTree;
94 using android::vold::VoldNativeService;
95 using android::vold::VolumeBase;
96 
97 static const char* kPathUserMount = "/mnt/user";
98 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
99 
100 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
101 
102 static const std::string kEmptyString("");
103 
104 /* 512MiB is large enough for testing purposes */
105 static const unsigned int kSizeVirtualDisk = 536870912;
106 
107 static const unsigned int kMajorBlockMmc = 179;
108 
109 using ScanProcCallback = bool(*)(uid_t uid, pid_t pid, int nsFd, const char* name, void* params);
110 
111 VolumeManager* VolumeManager::sInstance = NULL;
112 
Instance()113 VolumeManager* VolumeManager::Instance() {
114     if (!sInstance) sInstance = new VolumeManager();
115     return sInstance;
116 }
117 
VolumeManager()118 VolumeManager::VolumeManager() {
119     mDebug = false;
120     mNextObbId = 0;
121     mNextStubId = 0;
122     // For security reasons, assume that a secure keyguard is
123     // showing until we hear otherwise
124     mSecureKeyguardShowing = true;
125 }
126 
~VolumeManager()127 VolumeManager::~VolumeManager() {}
128 
updateVirtualDisk()129 int VolumeManager::updateVirtualDisk() {
130     ATRACE_NAME("VolumeManager::updateVirtualDisk");
131     if (GetBoolProperty(kPropVirtualDisk, false)) {
132         if (access(kPathVirtualDisk, F_OK) != 0) {
133             Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
134         }
135 
136         if (mVirtualDisk == nullptr) {
137             if (Loop::create(kPathVirtualDisk, mVirtualDiskPath) != 0) {
138                 LOG(ERROR) << "Failed to create virtual disk";
139                 return -1;
140             }
141 
142             struct stat buf;
143             if (stat(mVirtualDiskPath.c_str(), &buf) < 0) {
144                 PLOG(ERROR) << "Failed to stat " << mVirtualDiskPath;
145                 return -1;
146             }
147 
148             auto disk = new android::vold::Disk(
149                 "virtual", buf.st_rdev, "virtual",
150                 android::vold::Disk::Flags::kAdoptable | android::vold::Disk::Flags::kSd);
151             mVirtualDisk = std::shared_ptr<android::vold::Disk>(disk);
152             handleDiskAdded(mVirtualDisk);
153         }
154     } else {
155         if (mVirtualDisk != nullptr) {
156             dev_t device = mVirtualDisk->getDevice();
157             handleDiskRemoved(device);
158 
159             Loop::destroyByDevice(mVirtualDiskPath.c_str());
160             mVirtualDisk = nullptr;
161         }
162 
163         if (access(kPathVirtualDisk, F_OK) == 0) {
164             unlink(kPathVirtualDisk);
165         }
166     }
167     return 0;
168 }
169 
setDebug(bool enable)170 int VolumeManager::setDebug(bool enable) {
171     mDebug = enable;
172     return 0;
173 }
174 
start()175 int VolumeManager::start() {
176     ATRACE_NAME("VolumeManager::start");
177 
178     // Always start from a clean slate by unmounting everything in
179     // directories that we own, in case we crashed.
180     unmountAll();
181 
182     Devmapper::destroyAll();
183     Loop::destroyAll();
184 
185     // Assume that we always have an emulated volume on internal
186     // storage; the framework will decide if it should be mounted.
187     CHECK(mInternalEmulatedVolumes.empty());
188 
189     auto vol = std::shared_ptr<android::vold::VolumeBase>(
190             new android::vold::EmulatedVolume("/data/media", 0));
191     vol->setMountUserId(0);
192     vol->create();
193     mInternalEmulatedVolumes.push_back(vol);
194 
195     // Consider creating a virtual disk
196     updateVirtualDisk();
197 
198     return 0;
199 }
200 
stop()201 int VolumeManager::stop() {
202     CHECK(!mInternalEmulatedVolumes.empty());
203     for (const auto& vol : mInternalEmulatedVolumes) {
204         vol->destroy();
205     }
206     mInternalEmulatedVolumes.clear();
207 
208     return 0;
209 }
210 
handleBlockEvent(NetlinkEvent * evt)211 void VolumeManager::handleBlockEvent(NetlinkEvent* evt) {
212     std::lock_guard<std::mutex> lock(mLock);
213 
214     if (mDebug) {
215         LOG(DEBUG) << "----------------";
216         LOG(DEBUG) << "handleBlockEvent with action " << (int)evt->getAction();
217         evt->dump();
218     }
219 
220     std::string eventPath(evt->findParam("DEVPATH") ? evt->findParam("DEVPATH") : "");
221     std::string devType(evt->findParam("DEVTYPE") ? evt->findParam("DEVTYPE") : "");
222 
223     if (devType != "disk") return;
224 
225     int major = std::stoi(evt->findParam("MAJOR"));
226     int minor = std::stoi(evt->findParam("MINOR"));
227     dev_t device = makedev(major, minor);
228 
229     switch (evt->getAction()) {
230         case NetlinkEvent::Action::kAdd: {
231             for (const auto& source : mDiskSources) {
232                 if (source->matches(eventPath)) {
233                     // For now, assume that MMC and virtio-blk (the latter is
234                     // specific to virtual platforms; see Utils.cpp for details)
235                     // devices are SD, and that everything else is USB
236                     int flags = source->getFlags();
237                     if (major == kMajorBlockMmc || IsVirtioBlkDevice(major)) {
238                         flags |= android::vold::Disk::Flags::kSd;
239                     } else {
240                         flags |= android::vold::Disk::Flags::kUsb;
241                     }
242 
243                     auto disk =
244                         new android::vold::Disk(eventPath, device, source->getNickname(), flags);
245                     handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk));
246                     break;
247                 }
248             }
249             break;
250         }
251         case NetlinkEvent::Action::kChange: {
252             LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
253             handleDiskChanged(device);
254             break;
255         }
256         case NetlinkEvent::Action::kRemove: {
257             handleDiskRemoved(device);
258             break;
259         }
260         default: {
261             LOG(WARNING) << "Unexpected block event action " << (int)evt->getAction();
262             break;
263         }
264     }
265 }
266 
handleDiskAdded(const std::shared_ptr<android::vold::Disk> & disk)267 void VolumeManager::handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk) {
268     // For security reasons, if secure keyguard is showing, wait
269     // until the user unlocks the device to actually touch it
270     // Additionally, wait until user 0 is actually started, since we need
271     // the user to be up before we can mount a FUSE daemon to handle the disk.
272     bool userZeroStarted = mStartedUsers.find(0) != mStartedUsers.end();
273     if (mSecureKeyguardShowing) {
274         LOG(INFO) << "Found disk at " << disk->getEventPath()
275                   << " but delaying scan due to secure keyguard";
276         mPendingDisks.push_back(disk);
277     } else if (!userZeroStarted) {
278         LOG(INFO) << "Found disk at " << disk->getEventPath()
279                   << " but delaying scan due to user zero not having started";
280         mPendingDisks.push_back(disk);
281     } else {
282         disk->create();
283         mDisks.push_back(disk);
284     }
285 }
286 
handleDiskChanged(dev_t device)287 void VolumeManager::handleDiskChanged(dev_t device) {
288     for (const auto& disk : mDisks) {
289         if (disk->getDevice() == device) {
290             disk->readMetadata();
291             disk->readPartitions();
292         }
293     }
294 
295     // For security reasons, we ignore all pending disks, since
296     // we'll scan them once the device is unlocked
297 }
298 
handleDiskRemoved(dev_t device)299 void VolumeManager::handleDiskRemoved(dev_t device) {
300     auto i = mDisks.begin();
301     while (i != mDisks.end()) {
302         if ((*i)->getDevice() == device) {
303             (*i)->destroy();
304             i = mDisks.erase(i);
305         } else {
306             ++i;
307         }
308     }
309     auto j = mPendingDisks.begin();
310     while (j != mPendingDisks.end()) {
311         if ((*j)->getDevice() == device) {
312             j = mPendingDisks.erase(j);
313         } else {
314             ++j;
315         }
316     }
317 }
318 
addDiskSource(const std::shared_ptr<DiskSource> & diskSource)319 void VolumeManager::addDiskSource(const std::shared_ptr<DiskSource>& diskSource) {
320     std::lock_guard<std::mutex> lock(mLock);
321     mDiskSources.push_back(diskSource);
322 }
323 
findDisk(const std::string & id)324 std::shared_ptr<android::vold::Disk> VolumeManager::findDisk(const std::string& id) {
325     for (auto disk : mDisks) {
326         if (disk->getId() == id) {
327             return disk;
328         }
329     }
330     return nullptr;
331 }
332 
findVolume(const std::string & id)333 std::shared_ptr<android::vold::VolumeBase> VolumeManager::findVolume(const std::string& id) {
334     for (const auto& vol : mInternalEmulatedVolumes) {
335         if (vol->getId() == id) {
336             return vol;
337         }
338     }
339     for (const auto& disk : mDisks) {
340         auto vol = disk->findVolume(id);
341         if (vol != nullptr) {
342             return vol;
343         }
344     }
345     for (const auto& vol : mObbVolumes) {
346         if (vol->getId() == id) {
347             return vol;
348         }
349     }
350     return nullptr;
351 }
352 
listVolumes(android::vold::VolumeBase::Type type,std::list<std::string> & list) const353 void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
354                                 std::list<std::string>& list) const {
355     list.clear();
356     for (const auto& disk : mDisks) {
357         disk->listVolumes(type, list);
358     }
359 }
360 
forgetPartition(const std::string & partGuid,const std::string & fsUuid)361 int VolumeManager::forgetPartition(const std::string& partGuid, const std::string& fsUuid) {
362     std::string normalizedGuid;
363     if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
364         LOG(WARNING) << "Invalid GUID " << partGuid;
365         return -1;
366     }
367 
368     bool success = true;
369     std::string keyPath = android::vold::BuildKeyPath(normalizedGuid);
370     if (unlink(keyPath.c_str()) != 0) {
371         LOG(ERROR) << "Failed to unlink " << keyPath;
372         success = false;
373     }
374     if (fscrypt_is_native()) {
375         if (!fscrypt_destroy_volume_keys(fsUuid)) {
376             success = false;
377         }
378     }
379     return success ? 0 : -1;
380 }
381 
linkPrimary(userid_t userId)382 int VolumeManager::linkPrimary(userid_t userId) {
383     if (!GetBoolProperty(android::vold::kPropFuse, false)) {
384         std::string source(mPrimary->getPath());
385         if (mPrimary->isEmulated()) {
386             source = StringPrintf("%s/%d", source.c_str(), userId);
387             fs_prepare_dir(source.c_str(), 0755, AID_ROOT, AID_ROOT);
388         }
389 
390         std::string target(StringPrintf("/mnt/user/%d/primary", userId));
391         LOG(DEBUG) << "Linking " << source << " to " << target;
392         Symlink(source, target);
393     }
394     return 0;
395 }
396 
destroyEmulatedVolumesForUser(userid_t userId)397 void VolumeManager::destroyEmulatedVolumesForUser(userid_t userId) {
398     // Destroy and remove all unstacked EmulatedVolumes for the user
399     auto i = mInternalEmulatedVolumes.begin();
400     while (i != mInternalEmulatedVolumes.end()) {
401         auto vol = *i;
402         if (vol->getMountUserId() == userId) {
403             vol->destroy();
404             i = mInternalEmulatedVolumes.erase(i);
405         } else {
406             i++;
407         }
408     }
409 
410     // Destroy and remove all stacked EmulatedVolumes for the user on each mounted private volume
411     std::list<std::string> private_vols;
412     listVolumes(VolumeBase::Type::kPrivate, private_vols);
413     for (const std::string& id : private_vols) {
414         PrivateVolume* pvol = static_cast<PrivateVolume*>(findVolume(id).get());
415         std::list<std::shared_ptr<VolumeBase>> vols_to_remove;
416         if (pvol->getState() == VolumeBase::State::kMounted) {
417             for (const auto& vol : pvol->getVolumes()) {
418                 if (vol->getMountUserId() == userId) {
419                     vols_to_remove.push_back(vol);
420                 }
421             }
422             for (const auto& vol : vols_to_remove) {
423                 vol->destroy();
424                 pvol->removeVolume(vol);
425             }
426         }  // else EmulatedVolumes will be destroyed on VolumeBase#unmount
427     }
428 }
429 
createEmulatedVolumesForUser(userid_t userId)430 void VolumeManager::createEmulatedVolumesForUser(userid_t userId) {
431     // Create unstacked EmulatedVolumes for the user
432     auto vol = std::shared_ptr<android::vold::VolumeBase>(
433             new android::vold::EmulatedVolume("/data/media", userId));
434     vol->setMountUserId(userId);
435     mInternalEmulatedVolumes.push_back(vol);
436     vol->create();
437 
438     // Create stacked EmulatedVolumes for the user on each PrivateVolume
439     std::list<std::string> private_vols;
440     listVolumes(VolumeBase::Type::kPrivate, private_vols);
441     for (const std::string& id : private_vols) {
442         PrivateVolume* pvol = static_cast<PrivateVolume*>(findVolume(id).get());
443         if (pvol->getState() == VolumeBase::State::kMounted) {
444             auto evol =
445                     std::shared_ptr<android::vold::VolumeBase>(new android::vold::EmulatedVolume(
446                             pvol->getPath() + "/media", pvol->getRawDevice(), pvol->getFsUuid(),
447                             userId));
448             evol->setMountUserId(userId);
449             pvol->addVolume(evol);
450             evol->create();
451         }  // else EmulatedVolumes will be created per user when on PrivateVolume#doMount
452     }
453 }
454 
onUserAdded(userid_t userId,int userSerialNumber)455 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
456     LOG(INFO) << "onUserAdded: " << userId;
457 
458     mAddedUsers[userId] = userSerialNumber;
459     return 0;
460 }
461 
onUserRemoved(userid_t userId)462 int VolumeManager::onUserRemoved(userid_t userId) {
463     LOG(INFO) << "onUserRemoved: " << userId;
464 
465     onUserStopped(userId);
466     mAddedUsers.erase(userId);
467     return 0;
468 }
469 
onUserStarted(userid_t userId)470 int VolumeManager::onUserStarted(userid_t userId) {
471     LOG(INFO) << "onUserStarted: " << userId;
472 
473     if (mStartedUsers.find(userId) == mStartedUsers.end()) {
474         createEmulatedVolumesForUser(userId);
475     }
476 
477     if (!GetBoolProperty(android::vold::kPropFuse, false)) {
478         // Note that sometimes the system will spin up processes from Zygote
479         // before actually starting the user, so we're okay if Zygote
480         // already created this directory.
481         std::string path(StringPrintf("%s/%d", kPathUserMount, userId));
482         fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
483 
484         if (mPrimary) {
485             linkPrimary(userId);
486         }
487     }
488 
489     mStartedUsers.insert(userId);
490 
491     createPendingDisksIfNeeded();
492     return 0;
493 }
494 
onUserStopped(userid_t userId)495 int VolumeManager::onUserStopped(userid_t userId) {
496     LOG(VERBOSE) << "onUserStopped: " << userId;
497 
498     if (mStartedUsers.find(userId) != mStartedUsers.end()) {
499         destroyEmulatedVolumesForUser(userId);
500     }
501 
502     mStartedUsers.erase(userId);
503     return 0;
504 }
505 
createPendingDisksIfNeeded()506 void VolumeManager::createPendingDisksIfNeeded() {
507     bool userZeroStarted = mStartedUsers.find(0) != mStartedUsers.end();
508     if (!mSecureKeyguardShowing && userZeroStarted) {
509         // Now that secure keyguard has been dismissed and user 0 has
510         // started, process any pending disks
511         for (const auto& disk : mPendingDisks) {
512             disk->create();
513             mDisks.push_back(disk);
514         }
515         mPendingDisks.clear();
516     }
517 }
518 
onSecureKeyguardStateChanged(bool isShowing)519 int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) {
520     mSecureKeyguardShowing = isShowing;
521     createPendingDisksIfNeeded();
522     return 0;
523 }
524 
setPrimary(const std::shared_ptr<android::vold::VolumeBase> & vol)525 int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
526     mPrimary = vol;
527     for (userid_t userId : mStartedUsers) {
528         linkPrimary(userId);
529     }
530     return 0;
531 }
532 
533 // This code is executed after a fork so it's very important that the set of
534 // methods we call here is strictly limited.
535 //
536 // TODO: Get rid of this guesswork altogether and instead exec a process
537 // immediately after fork to do our bindding for us.
childProcess(const char * storageSource,const char * userSource,int nsFd,const char * name)538 static bool childProcess(const char* storageSource, const char* userSource, int nsFd,
539                          const char* name) {
540     if (setns(nsFd, CLONE_NEWNS) != 0) {
541         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to setns for %s :%s", name,
542                               strerror(errno));
543         return false;
544     }
545 
546     // NOTE: Inlined from vold::UnmountTree here to avoid using PLOG methods and
547     // to also protect against future changes that may cause issues across a
548     // fork.
549     if (TEMP_FAILURE_RETRY(umount2("/storage/", MNT_DETACH)) < 0 && errno != EINVAL &&
550         errno != ENOENT) {
551         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to unmount /storage/ :%s",
552                               strerror(errno));
553         return false;
554     }
555 
556     if (TEMP_FAILURE_RETRY(mount(storageSource, "/storage", NULL, MS_BIND | MS_REC, NULL)) == -1) {
557         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to mount %s for %s :%s",
558                               storageSource, name, strerror(errno));
559         return false;
560     }
561 
562     if (TEMP_FAILURE_RETRY(mount(NULL, "/storage", NULL, MS_REC | MS_SLAVE, NULL)) == -1) {
563         async_safe_format_log(ANDROID_LOG_ERROR, "vold",
564                               "Failed to set MS_SLAVE to /storage for %s :%s", name,
565                               strerror(errno));
566         return false;
567     }
568 
569     if (TEMP_FAILURE_RETRY(mount(userSource, "/storage/self", NULL, MS_BIND, NULL)) == -1) {
570         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to mount %s for %s :%s",
571                               userSource, name, strerror(errno));
572         return false;
573     }
574 
575     return true;
576 }
577 
578 // Fork the process and remount storage
forkAndRemountChild(uid_t uid,pid_t pid,int nsFd,const char * name,void * params)579 bool forkAndRemountChild(uid_t uid, pid_t pid, int nsFd, const char* name, void* params) {
580     int32_t mountMode = *static_cast<int32_t*>(params);
581     std::string userSource;
582     std::string storageSource;
583     pid_t child;
584     // Need to fix these paths to account for when sdcardfs is gone
585     switch (mountMode) {
586         case VoldNativeService::REMOUNT_MODE_NONE:
587             return true;
588         case VoldNativeService::REMOUNT_MODE_DEFAULT:
589             storageSource = "/mnt/runtime/default";
590             break;
591         case VoldNativeService::REMOUNT_MODE_READ:
592             storageSource = "/mnt/runtime/read";
593             break;
594         case VoldNativeService::REMOUNT_MODE_WRITE:
595         case VoldNativeService::REMOUNT_MODE_LEGACY:
596         case VoldNativeService::REMOUNT_MODE_INSTALLER:
597             storageSource = "/mnt/runtime/write";
598             break;
599         case VoldNativeService::REMOUNT_MODE_FULL:
600             storageSource = "/mnt/runtime/full";
601             break;
602         case VoldNativeService::REMOUNT_MODE_PASS_THROUGH:
603             return true;
604         default:
605             PLOG(ERROR) << "Unknown mode " << std::to_string(mountMode);
606             return false;
607     }
608     LOG(DEBUG) << "Remounting " << uid << " as " << storageSource;
609 
610     // Fork a child to mount user-specific symlink helper into place
611     userSource = StringPrintf("/mnt/user/%d", multiuser_get_user_id(uid));
612     if (!(child = fork())) {
613         if (childProcess(storageSource.c_str(), userSource.c_str(), nsFd, name)) {
614             _exit(0);
615         } else {
616             _exit(1);
617         }
618     }
619 
620     if (child == -1) {
621         PLOG(ERROR) << "Failed to fork";
622         return false;
623     } else {
624         TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
625     }
626     return true;
627 }
628 
629 // Helper function to scan all processes in /proc and call the callback if:
630 // 1). pid belongs to an app process
631 // 2). If input uid is 0 or it matches the process uid
632 // 3). If userId is not -1 or userId matches the process userId
scanProcProcesses(uid_t uid,userid_t userId,ScanProcCallback callback,void * params)633 bool scanProcProcesses(uid_t uid, userid_t userId, ScanProcCallback callback, void* params) {
634     DIR* dir;
635     struct dirent* de;
636     std::string rootName;
637     std::string pidName;
638     int pidFd;
639     int nsFd;
640     struct stat sb;
641 
642     static bool apexUpdatable = android::sysprop::ApexProperties::updatable().value_or(false);
643 
644     if (!(dir = opendir("/proc"))) {
645         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to opendir");
646         return false;
647     }
648 
649     // Figure out root namespace to compare against below
650     if (!android::vold::Readlinkat(dirfd(dir), "1/ns/mnt", &rootName)) {
651         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to read root namespace");
652         closedir(dir);
653         return false;
654     }
655 
656     async_safe_format_log(ANDROID_LOG_INFO, "vold", "Start scanning all processes");
657     // Poke through all running PIDs look for apps running as UID
658     while ((de = readdir(dir))) {
659         pid_t pid;
660         if (de->d_type != DT_DIR) continue;
661         if (!android::base::ParseInt(de->d_name, &pid)) continue;
662 
663         pidFd = -1;
664         nsFd = -1;
665 
666         pidFd = openat(dirfd(dir), de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
667         if (pidFd < 0) {
668             goto next;
669         }
670         if (fstat(pidFd, &sb) != 0) {
671             async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to stat %s", de->d_name);
672             goto next;
673         }
674         if (uid != 0 && sb.st_uid != uid) {
675             goto next;
676         }
677         if (userId != static_cast<userid_t>(-1) && multiuser_get_user_id(sb.st_uid) != userId) {
678             goto next;
679         }
680 
681         // Matches so far, but refuse to touch if in root namespace
682         if (!android::vold::Readlinkat(pidFd, "ns/mnt", &pidName)) {
683             async_safe_format_log(ANDROID_LOG_ERROR, "vold",
684                     "Failed to read namespacefor %s", de->d_name);
685             goto next;
686         }
687         if (rootName == pidName) {
688             goto next;
689         }
690 
691         if (apexUpdatable) {
692             std::string exeName;
693             // When ro.apex.bionic_updatable is set to true,
694             // some early native processes have mount namespaces that are different
695             // from that of the init. Therefore, above check can't filter them out.
696             // Since the propagation type of / is 'shared', unmounting /storage
697             // for the early native processes affects other processes including
698             // init. Filter out such processes by skipping if a process is a
699             // non-Java process whose UID is < AID_APP_START. (The UID condition
700             // is required to not filter out child processes spawned by apps.)
701             if (!android::vold::Readlinkat(pidFd, "exe", &exeName)) {
702                 goto next;
703             }
704             if (!StartsWith(exeName, "/system/bin/app_process") && sb.st_uid < AID_APP_START) {
705                 goto next;
706             }
707         }
708 
709         // We purposefully leave the namespace open across the fork
710         // NOLINTNEXTLINE(android-cloexec-open): Deliberately not O_CLOEXEC
711         nsFd = openat(pidFd, "ns/mnt", O_RDONLY);
712         if (nsFd < 0) {
713             async_safe_format_log(ANDROID_LOG_ERROR, "vold",
714                     "Failed to open namespace for %s", de->d_name);
715             goto next;
716         }
717 
718         if (!callback(sb.st_uid, pid, nsFd, de->d_name, params)) {
719             async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed in callback");
720         }
721 
722     next:
723         close(nsFd);
724         close(pidFd);
725     }
726     closedir(dir);
727     async_safe_format_log(ANDROID_LOG_INFO, "vold", "Finished scanning all processes");
728     return true;
729 }
730 
remountUid(uid_t uid,int32_t mountMode)731 int VolumeManager::remountUid(uid_t uid, int32_t mountMode) {
732     if (GetBoolProperty(android::vold::kPropFuse, false)) {
733         // TODO(135341433): Implement fuse specific logic.
734         return 0;
735     }
736     return scanProcProcesses(uid, static_cast<userid_t>(-1),
737             forkAndRemountChild, &mountMode) ? 0 : -1;
738 }
739 
740 
741 // In each app's namespace, mount tmpfs on obb and data dir, and bind mount obb and data
742 // package dirs.
remountStorageDirs(int nsFd,const char * android_data_dir,const char * android_obb_dir,int uid,const char * sources[],const char * targets[],int size)743 static bool remountStorageDirs(int nsFd, const char* android_data_dir, const char* android_obb_dir,
744         int uid, const char* sources[], const char* targets[], int size) {
745     // This code is executed after a fork so it's very important that the set of
746     // methods we call here is strictly limited.
747     if (setns(nsFd, CLONE_NEWNS) != 0) {
748         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to setns %s", strerror(errno));
749         return false;
750     }
751 
752     // Mount tmpfs on Android/data and Android/obb
753     if (TEMP_FAILURE_RETRY(mount("tmpfs", android_data_dir, "tmpfs",
754             MS_NOSUID | MS_NODEV | MS_NOEXEC, "uid=0,gid=0,mode=0751")) == -1) {
755         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to mount tmpfs to %s :%s",
756                         android_data_dir, strerror(errno));
757         return false;
758     }
759     if (TEMP_FAILURE_RETRY(mount("tmpfs", android_obb_dir, "tmpfs",
760             MS_NOSUID | MS_NODEV | MS_NOEXEC, "uid=0,gid=0,mode=0751")) == -1) {
761         async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to mount tmpfs to %s :%s",
762                 android_obb_dir, strerror(errno));
763         return false;
764     }
765 
766     for (int i = 0; i < size; i++) {
767         // Create package dir and bind mount it to the actual one.
768         if (TEMP_FAILURE_RETRY(mkdir(targets[i], 0700)) == -1) {
769             async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to mkdir %s %s",
770                     targets[i], strerror(errno));
771             return false;
772         }
773         if (TEMP_FAILURE_RETRY(mount(sources[i], targets[i], NULL, MS_BIND | MS_REC, NULL)) == -1) {
774             async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to mount %s to %s :%s",
775                                   sources[i], targets[i], strerror(errno));
776             return false;
777         }
778     }
779     return true;
780 }
781 
getStorageDirSrc(userid_t userId,const std::string & dirName,const std::string & packageName)782 static std::string getStorageDirSrc(userid_t userId, const std::string& dirName,
783         const std::string& packageName) {
784     if (IsSdcardfsUsed()) {
785         return StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s",
786                 userId, dirName.c_str(), packageName.c_str());
787     } else {
788         return StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s",
789                 userId, userId, dirName.c_str(), packageName.c_str());
790     }
791 }
792 
getStorageDirTarget(userid_t userId,std::string dirName,std::string packageName)793 static std::string getStorageDirTarget(userid_t userId, std::string dirName,
794         std::string packageName) {
795     return StringPrintf("/storage/emulated/%d/%s/%s",
796             userId, dirName.c_str(), packageName.c_str());
797 }
798 
799 // Fork the process and remount storage
forkAndRemountStorage(int uid,int pid,const std::vector<std::string> & packageNames)800 bool VolumeManager::forkAndRemountStorage(int uid, int pid,
801                                           const std::vector<std::string>& packageNames) {
802     userid_t userId = multiuser_get_user_id(uid);
803     std::string mnt_path = StringPrintf("/proc/%d/ns/mnt", pid);
804     android::base::unique_fd nsFd(
805             TEMP_FAILURE_RETRY(open(mnt_path.c_str(), O_RDONLY | O_CLOEXEC)));
806     if (nsFd == -1) {
807         PLOG(ERROR) << "Unable to open " << mnt_path.c_str();
808         return false;
809     }
810     // Storing both Android/obb and Android/data paths.
811     int size = packageNames.size() * 2;
812 
813     std::unique_ptr<std::string[]> sources(new std::string[size]);
814     std::unique_ptr<std::string[]> targets(new std::string[size]);
815     std::unique_ptr<const char*[]> sources_uptr(new const char*[size]);
816     std::unique_ptr<const char*[]> targets_uptr(new const char*[size]);
817     const char** sources_cstr = sources_uptr.get();
818     const char** targets_cstr = targets_uptr.get();
819 
820     for (int i = 0; i < size; i += 2) {
821         std::string const& packageName = packageNames[i/2];
822         sources[i] = getStorageDirSrc(userId, "Android/data", packageName);
823         targets[i] = getStorageDirTarget(userId, "Android/data", packageName);
824         sources[i+1] = getStorageDirSrc(userId, "Android/obb", packageName);
825         targets[i+1] = getStorageDirTarget(userId, "Android/obb", packageName);
826 
827         sources_cstr[i] = sources[i].c_str();
828         targets_cstr[i] = targets[i].c_str();
829         sources_cstr[i+1] = sources[i+1].c_str();
830         targets_cstr[i+1] = targets[i+1].c_str();
831     }
832 
833     for (int i = 0; i < size; i++) {
834         auto status = EnsureDirExists(sources_cstr[i], 0771, AID_MEDIA_RW, AID_MEDIA_RW);
835         if (status != OK) {
836             PLOG(ERROR) << "Failed to create dir: " << sources_cstr[i];
837             return false;
838         }
839         // Make sure /storage/emulated/... paths are setup correctly
840         status = setupAppDir(targets_cstr[i], uid, false /* fixupExistingOnly */);
841         if (status != OK) {
842             PLOG(ERROR) << "Failed to create dir: " << targets_cstr[i];
843             return false;
844         }
845     }
846 
847     char android_data_dir[PATH_MAX];
848     char android_obb_dir[PATH_MAX];
849     snprintf(android_data_dir, PATH_MAX, "/storage/emulated/%d/Android/data", userId);
850     snprintf(android_obb_dir, PATH_MAX, "/storage/emulated/%d/Android/obb", userId);
851 
852     pid_t child;
853     // Fork a child to mount Android/obb android Android/data dirs, as we don't want it to affect
854     // original vold process mount namespace.
855     if (!(child = fork())) {
856         if (remountStorageDirs(nsFd, android_data_dir, android_obb_dir, uid,
857                 sources_cstr, targets_cstr, size)) {
858             _exit(0);
859         } else {
860             _exit(1);
861         }
862     }
863 
864     if (child == -1) {
865         PLOG(ERROR) << "Failed to fork";
866         return false;
867     } else {
868         int status;
869         if (TEMP_FAILURE_RETRY(waitpid(child, &status, 0)) == -1) {
870             PLOG(ERROR) << "Failed to waitpid: " << child;
871             return false;
872         }
873         if (!WIFEXITED(status)) {
874             PLOG(ERROR) << "Process did not exit normally, status: " << status;
875             return false;
876         }
877         if (WEXITSTATUS(status)) {
878             PLOG(ERROR) << "Process exited with code: " << WEXITSTATUS(status);
879             return false;
880         }
881     }
882     return true;
883 }
884 
remountAppStorageDirs(int uid,int pid,const std::vector<std::string> & packageNames)885 int VolumeManager::remountAppStorageDirs(int uid, int pid,
886         const std::vector<std::string>& packageNames) {
887     if (!GetBoolProperty(android::vold::kPropFuse, false)) {
888         return 0;
889     }
890     // Only run the remount if fuse is mounted for that user.
891     userid_t userId = multiuser_get_user_id(uid);
892     bool fuseMounted = false;
893     for (auto& vol : mInternalEmulatedVolumes) {
894         if (vol->getMountUserId() == userId && vol->getState() == VolumeBase::State::kMounted) {
895             auto* emulatedVol = static_cast<android::vold::EmulatedVolume*>(vol.get());
896             if (emulatedVol) {
897                 fuseMounted = emulatedVol->isFuseMounted();
898             }
899             break;
900         }
901     }
902     if (fuseMounted) {
903         forkAndRemountStorage(uid, pid, packageNames);
904     }
905     return 0;
906 }
907 
abortFuse()908 int VolumeManager::abortFuse() {
909     return android::vold::AbortFuseConnections();
910 }
911 
reset()912 int VolumeManager::reset() {
913     // Tear down all existing disks/volumes and start from a blank slate so
914     // newly connected framework hears all events.
915     for (const auto& vol : mInternalEmulatedVolumes) {
916         vol->destroy();
917     }
918     mInternalEmulatedVolumes.clear();
919 
920     for (const auto& disk : mDisks) {
921         disk->destroy();
922         disk->create();
923     }
924     updateVirtualDisk();
925     mAddedUsers.clear();
926     mStartedUsers.clear();
927     return 0;
928 }
929 
930 // Can be called twice (sequentially) during shutdown. should be safe for that.
shutdown()931 int VolumeManager::shutdown() {
932     if (mInternalEmulatedVolumes.empty()) {
933         return 0;  // already shutdown
934     }
935     android::vold::sSleepOnUnmount = false;
936     for (const auto& vol : mInternalEmulatedVolumes) {
937         vol->destroy();
938     }
939     for (const auto& disk : mDisks) {
940         disk->destroy();
941     }
942 
943     mInternalEmulatedVolumes.clear();
944     mDisks.clear();
945     mPendingDisks.clear();
946     android::vold::sSleepOnUnmount = true;
947 
948     return 0;
949 }
950 
unmountAll()951 int VolumeManager::unmountAll() {
952     std::lock_guard<std::mutex> lock(mLock);
953     ATRACE_NAME("VolumeManager::unmountAll()");
954 
955     // First, try gracefully unmounting all known devices
956     for (const auto& vol : mInternalEmulatedVolumes) {
957         vol->unmount();
958     }
959     for (const auto& disk : mDisks) {
960         disk->unmountAll();
961     }
962 
963     // Worst case we might have some stale mounts lurking around, so
964     // force unmount those just to be safe.
965     FILE* fp = setmntent("/proc/mounts", "re");
966     if (fp == NULL) {
967         PLOG(ERROR) << "Failed to open /proc/mounts";
968         return -errno;
969     }
970 
971     // Some volumes can be stacked on each other, so force unmount in
972     // reverse order to give us the best chance of success.
973     std::list<std::string> toUnmount;
974     mntent* mentry;
975     while ((mentry = getmntent(fp)) != NULL) {
976         auto test = std::string(mentry->mnt_dir);
977         if ((StartsWith(test, "/mnt/") &&
978 #ifdef __ANDROID_DEBUGGABLE__
979              !StartsWith(test, "/mnt/scratch") &&
980 #endif
981              !StartsWith(test, "/mnt/vendor") && !StartsWith(test, "/mnt/product") &&
982              !StartsWith(test, "/mnt/installer") && !StartsWith(test, "/mnt/androidwritable")) ||
983             StartsWith(test, "/storage/")) {
984             toUnmount.push_front(test);
985         }
986     }
987     endmntent(fp);
988 
989     for (const auto& path : toUnmount) {
990         LOG(DEBUG) << "Tearing down stale mount " << path;
991         android::vold::ForceUnmount(path);
992     }
993 
994     return 0;
995 }
996 
setupAppDir(const std::string & path,int32_t appUid,bool fixupExistingOnly)997 int VolumeManager::setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly) {
998     // Only offer to create directories for paths managed by vold
999     if (!StartsWith(path, "/storage/")) {
1000         LOG(ERROR) << "Failed to find mounted volume for " << path;
1001         return -EINVAL;
1002     }
1003 
1004     // Find the volume it belongs to
1005     auto filter_fn = [&](const VolumeBase& vol) {
1006         if (vol.getState() != VolumeBase::State::kMounted) {
1007             // The volume must be mounted
1008             return false;
1009         }
1010         if ((vol.getMountFlags() & VolumeBase::MountFlags::kVisible) == 0) {
1011             // and visible
1012             return false;
1013         }
1014         if (vol.getInternalPath().empty()) {
1015             return false;
1016         }
1017         if (vol.getMountUserId() != USER_UNKNOWN &&
1018             vol.getMountUserId() != multiuser_get_user_id(appUid)) {
1019             // The app dir must be created on a volume with the same user-id
1020             return false;
1021         }
1022         if (!path.empty() && StartsWith(path, vol.getPath())) {
1023             return true;
1024         }
1025 
1026         return false;
1027     };
1028     auto volume = findVolumeWithFilter(filter_fn);
1029     if (volume == nullptr) {
1030         LOG(ERROR) << "Failed to find mounted volume for " << path;
1031         return -EINVAL;
1032     }
1033     // Convert paths to lower filesystem paths to avoid making FUSE requests for these reasons:
1034     // 1. A FUSE request from vold puts vold at risk of hanging if the FUSE daemon is down
1035     // 2. The FUSE daemon prevents requests on /mnt/user/0/emulated/<userid != 0> and a request
1036     // on /storage/emulated/10 means /mnt/user/0/emulated/10
1037     const std::string lowerPath =
1038             volume->getInternalPath() + path.substr(volume->getPath().length());
1039 
1040     const std::string volumeRoot = volume->getRootPath();  // eg /data/media/0
1041 
1042     if (fixupExistingOnly && (access(lowerPath.c_str(), F_OK) != 0)) {
1043         // Nothing to fixup
1044         return OK;
1045     }
1046 
1047     if (volume->getType() == VolumeBase::Type::kPublic) {
1048         // On public volumes, we don't need to setup permissions, as everything goes through
1049         // FUSE; just create the dirs and be done with it.
1050         return fs_mkdirs(lowerPath.c_str(), 0700);
1051     }
1052 
1053     // Create the app paths we need from the root
1054     return PrepareAppDirFromRoot(lowerPath, volumeRoot, appUid, fixupExistingOnly);
1055 }
1056 
fixupAppDir(const std::string & path,int32_t appUid)1057 int VolumeManager::fixupAppDir(const std::string& path, int32_t appUid) {
1058     if (IsSdcardfsUsed()) {
1059         //sdcardfs magically does this for us
1060         return OK;
1061     }
1062     return setupAppDir(path, appUid, true /* fixupExistingOnly */);
1063 }
1064 
createObb(const std::string & sourcePath,const std::string & sourceKey,int32_t ownerGid,std::string * outVolId)1065 int VolumeManager::createObb(const std::string& sourcePath, const std::string& sourceKey,
1066                              int32_t ownerGid, std::string* outVolId) {
1067     int id = mNextObbId++;
1068 
1069     std::string lowerSourcePath;
1070 
1071     // Convert to lower filesystem path
1072     if (StartsWith(sourcePath, "/storage/")) {
1073         auto filter_fn = [&](const VolumeBase& vol) {
1074             if (vol.getState() != VolumeBase::State::kMounted) {
1075                 // The volume must be mounted
1076                 return false;
1077             }
1078             if ((vol.getMountFlags() & VolumeBase::MountFlags::kVisible) == 0) {
1079                 // and visible
1080                 return false;
1081             }
1082             if (vol.getInternalPath().empty()) {
1083                 return false;
1084             }
1085             if (!sourcePath.empty() && StartsWith(sourcePath, vol.getPath())) {
1086                 return true;
1087             }
1088 
1089             return false;
1090         };
1091         auto volume = findVolumeWithFilter(filter_fn);
1092         if (volume == nullptr) {
1093             LOG(ERROR) << "Failed to find mounted volume for " << sourcePath;
1094             return -EINVAL;
1095         } else {
1096             lowerSourcePath =
1097                     volume->getInternalPath() + sourcePath.substr(volume->getPath().length());
1098         }
1099     } else {
1100         lowerSourcePath = sourcePath;
1101     }
1102 
1103     auto vol = std::shared_ptr<android::vold::VolumeBase>(
1104             new android::vold::ObbVolume(id, lowerSourcePath, sourceKey, ownerGid));
1105     vol->create();
1106 
1107     mObbVolumes.push_back(vol);
1108     *outVolId = vol->getId();
1109     return android::OK;
1110 }
1111 
destroyObb(const std::string & volId)1112 int VolumeManager::destroyObb(const std::string& volId) {
1113     auto i = mObbVolumes.begin();
1114     while (i != mObbVolumes.end()) {
1115         if ((*i)->getId() == volId) {
1116             (*i)->destroy();
1117             i = mObbVolumes.erase(i);
1118         } else {
1119             ++i;
1120         }
1121     }
1122     return android::OK;
1123 }
1124 
createStubVolume(const std::string & sourcePath,const std::string & mountPath,const std::string & fsType,const std::string & fsUuid,const std::string & fsLabel,int32_t flags,std::string * outVolId)1125 int VolumeManager::createStubVolume(const std::string& sourcePath, const std::string& mountPath,
1126                                     const std::string& fsType, const std::string& fsUuid,
1127                                     const std::string& fsLabel, int32_t flags,
1128                                     std::string* outVolId) {
1129     dev_t stubId = --mNextStubId;
1130     auto vol = std::shared_ptr<android::vold::StubVolume>(
1131             new android::vold::StubVolume(stubId, sourcePath, mountPath, fsType, fsUuid, fsLabel));
1132 
1133     int32_t passedFlags = android::vold::Disk::Flags::kStub;
1134     passedFlags |= (flags & android::vold::Disk::Flags::kUsb);
1135     passedFlags |= (flags & android::vold::Disk::Flags::kSd);
1136     // StubDisk doesn't have device node corresponds to it. So, a fake device
1137     // number is used.
1138     auto disk = std::shared_ptr<android::vold::Disk>(
1139             new android::vold::Disk("stub", stubId, "stub", passedFlags));
1140     disk->initializePartition(vol);
1141     handleDiskAdded(disk);
1142     *outVolId = vol->getId();
1143     return android::OK;
1144 }
1145 
destroyStubVolume(const std::string & volId)1146 int VolumeManager::destroyStubVolume(const std::string& volId) {
1147     auto tokens = android::base::Split(volId, ":");
1148     CHECK(tokens.size() == 2);
1149     dev_t stubId;
1150     CHECK(android::base::ParseUint(tokens[1], &stubId));
1151     handleDiskRemoved(stubId);
1152     return android::OK;
1153 }
1154 
mountAppFuse(uid_t uid,int mountId,unique_fd * device_fd)1155 int VolumeManager::mountAppFuse(uid_t uid, int mountId, unique_fd* device_fd) {
1156     return android::vold::MountAppFuse(uid, mountId, device_fd);
1157 }
1158 
unmountAppFuse(uid_t uid,int mountId)1159 int VolumeManager::unmountAppFuse(uid_t uid, int mountId) {
1160     return android::vold::UnmountAppFuse(uid, mountId);
1161 }
1162 
openAppFuseFile(uid_t uid,int mountId,int fileId,int flags)1163 int VolumeManager::openAppFuseFile(uid_t uid, int mountId, int fileId, int flags) {
1164     return android::vold::OpenAppFuseFile(uid, mountId, fileId, flags);
1165 }
1166