OSDN Git Service

vold: Honor mount options for ext4 partitions
[android-x86/system-vold.git] / VolumeManager.cpp
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 #include <dirent.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <fts.h>
21 #include <mntent.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/ioctl.h>
26 #include <sys/mount.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31
32 #include <linux/kdev_t.h>
33
34 #define LOG_TAG "Vold"
35
36 #include <openssl/md5.h>
37
38 #include <android-base/logging.h>
39 #include <android-base/stringprintf.h>
40 #include <cutils/fs.h>
41 #include <cutils/log.h>
42
43 #include <selinux/android.h>
44
45 #include <sysutils/NetlinkEvent.h>
46
47 #include <private/android_filesystem_config.h>
48
49 #include "Benchmark.h"
50 #include "EmulatedVolume.h"
51 #include "VolumeManager.h"
52 #include "NetlinkManager.h"
53 #include "ResponseCode.h"
54 #include "Loop.h"
55 #include "fs/Ext4.h"
56 #include "fs/Vfat.h"
57 #include "Utils.h"
58 #include "Devmapper.h"
59 #include "Process.h"
60 #include "Asec.h"
61 #include "VoldUtil.h"
62 #include "cryptfs.h"
63
64 #define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
65
66 #define ROUND_UP_POWER_OF_2(number, po2) (((!!((number) & ((1U << (po2)) - 1))) << (po2))\
67                                          + ((number) & (~((1U << (po2)) - 1))))
68
69 using android::base::StringPrintf;
70
71 /*
72  * Path to external storage where *only* root can access ASEC image files
73  */
74 const char *VolumeManager::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
75
76 /*
77  * Path to internal storage where *only* root can access ASEC image files
78  */
79 const char *VolumeManager::SEC_ASECDIR_INT   = "/data/app-asec";
80
81 /*
82  * Path to where secure containers are mounted
83  */
84 const char *VolumeManager::ASECDIR           = "/mnt/asec";
85
86 /*
87  * Path to where OBBs are mounted
88  */
89 const char *VolumeManager::LOOPDIR           = "/mnt/obb";
90
91 static const char* kPathUserMount = "/mnt/user";
92 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
93
94 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
95
96 /* 512MiB is large enough for testing purposes */
97 static const unsigned int kSizeVirtualDisk = 536870912;
98
99 static const unsigned int kMajorBlockMmc = 179;
100 static const unsigned int kMajorBlockExperimentalMin = 240;
101 static const unsigned int kMajorBlockExperimentalMax = 254;
102
103 /* writes superblock at end of file or device given by name */
104 static int writeSuperBlock(const char* name, struct asec_superblock *sb, unsigned int numImgSectors) {
105     int sbfd = open(name, O_RDWR | O_CLOEXEC);
106     if (sbfd < 0) {
107         SLOGE("Failed to open %s for superblock write (%s)", name, strerror(errno));
108         return -1;
109     }
110
111     if (lseek(sbfd, (numImgSectors * 512), SEEK_SET) < 0) {
112         SLOGE("Failed to lseek for superblock (%s)", strerror(errno));
113         close(sbfd);
114         return -1;
115     }
116
117     if (write(sbfd, sb, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
118         SLOGE("Failed to write superblock (%s)", strerror(errno));
119         close(sbfd);
120         return -1;
121     }
122     close(sbfd);
123     return 0;
124 }
125
126 static unsigned long adjustSectorNumExt4(unsigned long numSectors) {
127     // Ext4 started to reserve 2% or 4096 clusters, whichever is smaller for
128     // preventing costly operations or unexpected ENOSPC error.
129     // Ext4::format() uses default block size without clustering.
130     unsigned long clusterSectors = 4096 / 512;
131     unsigned long reservedSectors = (numSectors * 2)/100 + (numSectors % 50 > 0);
132     numSectors += reservedSectors > (4096 * clusterSectors) ? (4096 * clusterSectors) : reservedSectors;
133     return ROUND_UP_POWER_OF_2(numSectors, 3);
134 }
135
136 static unsigned long adjustSectorNumFAT(unsigned long numSectors) {
137     /*
138     * Add some headroom
139     */
140     unsigned long fatSize = (((numSectors * 4) / 512) + 1) * 2;
141     numSectors += fatSize + 2;
142     /*
143     * FAT is aligned to 32 kb with 512b sectors.
144     */
145     return ROUND_UP_POWER_OF_2(numSectors, 6);
146 }
147
148 static int setupLoopDevice(char* buffer, size_t len, const char* asecFileName, const char* idHash, bool debug) {
149     if (Loop::lookupActive(idHash, buffer, len)) {
150         if (Loop::create(idHash, asecFileName, buffer, len)) {
151             SLOGE("ASEC loop device creation failed for %s (%s)", asecFileName, strerror(errno));
152             return -1;
153         }
154         if (debug) {
155             SLOGD("New loop device created at %s", buffer);
156         }
157     } else {
158         if (debug) {
159             SLOGD("Found active loopback for %s at %s", asecFileName, buffer);
160         }
161     }
162     return 0;
163 }
164
165 static int setupDevMapperDevice(char* buffer, size_t len, const char* loopDevice, const char* asecFileName, const char* key, const char* idHash , unsigned long numImgSectors, bool* createdDMDevice, bool debug) {
166     if (strcmp(key, "none")) {
167         if (Devmapper::lookupActive(idHash, buffer, len)) {
168             if (Devmapper::create(idHash, loopDevice, key, numImgSectors,
169                                   buffer, len)) {
170                 SLOGE("ASEC device mapping failed for %s (%s)", asecFileName, strerror(errno));
171                 return -1;
172             }
173             if (debug) {
174                 SLOGD("New devmapper instance created at %s", buffer);
175             }
176         } else {
177             if (debug) {
178                 SLOGD("Found active devmapper for %s at %s", asecFileName, buffer);
179             }
180         }
181         *createdDMDevice = true;
182     } else {
183         strcpy(buffer, loopDevice);
184         *createdDMDevice = false;
185     }
186     return 0;
187 }
188
189 static void waitForDevMapper(const char *dmDevice) {
190     /*
191      * Wait for the device mapper node to be created. Sometimes it takes a
192      * while. Wait for up to 1 second. We could also inspect incoming uevents,
193      * but that would take more effort.
194      */
195     int tries = 25;
196     while (tries--) {
197         if (!access(dmDevice, F_OK) || errno != ENOENT) {
198             break;
199         }
200         usleep(40 * 1000);
201     }
202 }
203
204 VolumeManager *VolumeManager::sInstance = NULL;
205
206 VolumeManager *VolumeManager::Instance() {
207     if (!sInstance)
208         sInstance = new VolumeManager();
209     return sInstance;
210 }
211
212 VolumeManager::VolumeManager() {
213     mDebug = false;
214     mActiveContainers = new AsecIdCollection();
215     mBroadcaster = NULL;
216     mUmsSharingCount = 0;
217     mSavedDirtyRatio = -1;
218     // set dirty ratio to 0 when UMS is active
219     mUmsDirtyRatio = 0;
220 }
221
222 VolumeManager::~VolumeManager() {
223     delete mActiveContainers;
224 }
225
226 char *VolumeManager::asecHash(const char *id, char *buffer, size_t len) {
227     static const char* digits = "0123456789abcdef";
228
229     unsigned char sig[MD5_DIGEST_LENGTH];
230
231     if (buffer == NULL) {
232         SLOGE("Destination buffer is NULL");
233         errno = ESPIPE;
234         return NULL;
235     } else if (id == NULL) {
236         SLOGE("Source buffer is NULL");
237         errno = ESPIPE;
238         return NULL;
239     } else if (len < MD5_ASCII_LENGTH_PLUS_NULL) {
240         SLOGE("Target hash buffer size < %d bytes (%zu)",
241                 MD5_ASCII_LENGTH_PLUS_NULL, len);
242         errno = ESPIPE;
243         return NULL;
244     }
245
246     MD5(reinterpret_cast<const unsigned char*>(id), strlen(id), sig);
247
248     char *p = buffer;
249     for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
250         *p++ = digits[sig[i] >> 4];
251         *p++ = digits[sig[i] & 0x0F];
252     }
253     *p = '\0';
254
255     return buffer;
256 }
257
258 int VolumeManager::updateVirtualDisk() {
259     if (property_get_bool(kPropVirtualDisk, false)) {
260         if (access(kPathVirtualDisk, F_OK) != 0) {
261             Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
262         }
263
264         if (mVirtualDisk == nullptr) {
265             if (Loop::create(kPathVirtualDisk, mVirtualDiskPath) != 0) {
266                 LOG(ERROR) << "Failed to create virtual disk";
267                 return -1;
268             }
269
270             struct stat buf;
271             if (stat(mVirtualDiskPath.c_str(), &buf) < 0) {
272                 PLOG(ERROR) << "Failed to stat " << mVirtualDiskPath;
273                 return -1;
274             }
275
276             auto disk = new android::vold::Disk("virtual", buf.st_rdev, "virtual",
277                     android::vold::Disk::Flags::kAdoptable | android::vold::Disk::Flags::kSd);
278             disk->create();
279             mVirtualDisk = std::shared_ptr<android::vold::Disk>(disk);
280             mDisks.push_back(mVirtualDisk);
281         }
282     } else {
283         if (mVirtualDisk != nullptr) {
284             dev_t device = mVirtualDisk->getDevice();
285
286             auto i = mDisks.begin();
287             while (i != mDisks.end()) {
288                 if ((*i)->getDevice() == device) {
289                     (*i)->destroy();
290                     i = mDisks.erase(i);
291                 } else {
292                     ++i;
293                 }
294             }
295
296             Loop::destroyByDevice(mVirtualDiskPath.c_str());
297             mVirtualDisk = nullptr;
298         }
299
300         if (access(kPathVirtualDisk, F_OK) == 0) {
301             unlink(kPathVirtualDisk);
302         }
303     }
304     return 0;
305 }
306
307 int VolumeManager::setDebug(bool enable) {
308     mDebug = enable;
309     return 0;
310 }
311
312 int VolumeManager::start() {
313     // Always start from a clean slate by unmounting everything in
314     // directories that we own, in case we crashed.
315     unmountAll();
316
317     // Assume that we always have an emulated volume on internal
318     // storage; the framework will decide if it should be mounted.
319     CHECK(mInternalEmulated == nullptr);
320     mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(
321             new android::vold::EmulatedVolume("/data/media"));
322     mInternalEmulated->create();
323
324     // Consider creating a virtual disk
325     updateVirtualDisk();
326
327     return 0;
328 }
329
330 int VolumeManager::stop() {
331     CHECK(mInternalEmulated != nullptr);
332     mInternalEmulated->destroy();
333     mInternalEmulated = nullptr;
334     return 0;
335 }
336
337 void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
338     std::lock_guard<std::mutex> lock(mLock);
339
340     if (mDebug) {
341         LOG(VERBOSE) << "----------------";
342         LOG(VERBOSE) << "handleBlockEvent with action " << (int) evt->getAction();
343         evt->dump();
344     }
345
346     std::string eventPath(evt->findParam("DEVPATH")?evt->findParam("DEVPATH"):"");
347     std::string devType(evt->findParam("DEVTYPE")?evt->findParam("DEVTYPE"):"");
348
349     if (devType != "disk") return;
350
351     int major = atoi(evt->findParam("MAJOR"));
352     int minor = atoi(evt->findParam("MINOR"));
353     dev_t device = makedev(major, minor);
354
355     switch (evt->getAction()) {
356     case NetlinkEvent::Action::kAdd: {
357         for (const auto& source : mDiskSources) {
358             if (source->matches(eventPath)) {
359                 // For now, assume that MMC and virtio-blk (the latter is
360                 // emulator-specific; see Disk.cpp for details) devices are SD,
361                 // and that everything else is USB
362                 int flags = source->getFlags();
363                 if (major == kMajorBlockMmc
364                     || (android::vold::IsRunningInEmulator()
365                     && major >= (int) kMajorBlockExperimentalMin
366                     && major <= (int) kMajorBlockExperimentalMax)) {
367                     flags |= android::vold::Disk::Flags::kSd;
368                 } else {
369                     flags |= android::vold::Disk::Flags::kUsb;
370                 }
371
372                  android::vold::Disk* disk = (source->getPartNum() == -1) ?
373                         new android::vold::Disk(eventPath, device,
374                                 source->getNickname(), flags) :
375                         new android::vold::DiskPartition(eventPath, device,
376                                 source->getNickname(), flags,
377                                 source->getPartNum(),
378                                 source->getFsType(), source->getMntOpts());
379                 disk->create();
380                 mDisks.push_back(std::shared_ptr<android::vold::Disk>(disk));
381                 break;
382             }
383         }
384         break;
385     }
386     case NetlinkEvent::Action::kChange: {
387         LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
388         for (const auto& disk : mDisks) {
389             if (disk->getDevice() == device) {
390                 disk->readMetadata();
391                 disk->readPartitions();
392             }
393         }
394         break;
395     }
396     case NetlinkEvent::Action::kRemove: {
397         auto i = mDisks.begin();
398         while (i != mDisks.end()) {
399             if ((*i)->getDevice() == device) {
400                 (*i)->destroy();
401                 i = mDisks.erase(i);
402             } else {
403                 ++i;
404             }
405         }
406         break;
407     }
408     default: {
409         LOG(WARNING) << "Unexpected block event action " << (int) evt->getAction();
410         break;
411     }
412     }
413 }
414
415 void VolumeManager::addDiskSource(const std::shared_ptr<DiskSource>& diskSource) {
416     std::lock_guard<std::mutex> lock(mLock);
417     mDiskSources.push_back(diskSource);
418 }
419
420 std::shared_ptr<android::vold::Disk> VolumeManager::findDisk(const std::string& id) {
421     for (auto disk : mDisks) {
422         if (disk->getId() == id) {
423             return disk;
424         }
425     }
426     return nullptr;
427 }
428
429 std::shared_ptr<android::vold::VolumeBase> VolumeManager::findVolume(const std::string& id) {
430     if (mInternalEmulated->getId() == id) {
431         return mInternalEmulated;
432     }
433     for (const auto& disk : mDisks) {
434         auto vol = disk->findVolume(id);
435         if (vol != nullptr) {
436             return vol;
437         }
438     }
439     return nullptr;
440 }
441
442 void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
443         std::list<std::string>& list) {
444     list.clear();
445     for (const auto& disk : mDisks) {
446         disk->listVolumes(type, list);
447     }
448 }
449
450 nsecs_t VolumeManager::benchmarkPrivate(const std::string& id) {
451     std::string path;
452     if (id == "private" || id == "null") {
453         path = "/data";
454     } else {
455         auto vol = findVolume(id);
456         if (vol != nullptr && vol->getState() == android::vold::VolumeBase::State::kMounted) {
457             path = vol->getPath();
458         }
459     }
460
461     if (path.empty()) {
462         LOG(WARNING) << "Failed to find volume for " << id;
463         return -1;
464     }
465
466     return android::vold::BenchmarkPrivate(path);
467 }
468
469 int VolumeManager::forgetPartition(const std::string& partGuid) {
470     std::string normalizedGuid;
471     if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
472         LOG(WARNING) << "Invalid GUID " << partGuid;
473         return -1;
474     }
475
476     std::string keyPath = android::vold::BuildKeyPath(normalizedGuid);
477     if (unlink(keyPath.c_str()) != 0) {
478         LOG(ERROR) << "Failed to unlink " << keyPath;
479         return -1;
480     }
481
482     return 0;
483 }
484
485 int VolumeManager::linkPrimary(userid_t userId) {
486     std::string source(mPrimary->getPath());
487     if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
488         source = StringPrintf("%s/%d", source.c_str(), userId);
489         fs_prepare_dir(source.c_str(), 0755, AID_ROOT, AID_ROOT);
490     }
491
492     std::string target(StringPrintf("/mnt/user/%d/primary", userId));
493     if (TEMP_FAILURE_RETRY(unlink(target.c_str()))) {
494         if (errno != ENOENT) {
495             SLOGW("Failed to unlink %s: %s", target.c_str(), strerror(errno));
496         }
497     }
498     LOG(DEBUG) << "Linking " << source << " to " << target;
499     if (TEMP_FAILURE_RETRY(symlink(source.c_str(), target.c_str()))) {
500         SLOGW("Failed to link %s to %s: %s", source.c_str(), target.c_str(),
501                 strerror(errno));
502         return -errno;
503     }
504     return 0;
505 }
506
507 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
508     mAddedUsers[userId] = userSerialNumber;
509     return 0;
510 }
511
512 int VolumeManager::onUserRemoved(userid_t userId) {
513     mAddedUsers.erase(userId);
514     return 0;
515 }
516
517 int VolumeManager::onUserStarted(userid_t userId) {
518     // Note that sometimes the system will spin up processes from Zygote
519     // before actually starting the user, so we're okay if Zygote
520     // already created this directory.
521     std::string path(StringPrintf("%s/%d", kPathUserMount, userId));
522     fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
523
524     mStartedUsers.insert(userId);
525     if (mPrimary) {
526         linkPrimary(userId);
527     }
528     return 0;
529 }
530
531 int VolumeManager::onUserStopped(userid_t userId) {
532     mStartedUsers.erase(userId);
533     return 0;
534 }
535
536 int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
537     mPrimary = vol;
538     for (userid_t userId : mStartedUsers) {
539         linkPrimary(userId);
540     }
541     return 0;
542 }
543
544 static int unmount_tree(const char* path) {
545     size_t path_len = strlen(path);
546
547     FILE* fp = setmntent("/proc/mounts", "r");
548     if (fp == NULL) {
549         ALOGE("Error opening /proc/mounts: %s", strerror(errno));
550         return -errno;
551     }
552
553     // Some volumes can be stacked on each other, so force unmount in
554     // reverse order to give us the best chance of success.
555     std::list<std::string> toUnmount;
556     mntent* mentry;
557     while ((mentry = getmntent(fp)) != NULL) {
558         if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
559             toUnmount.push_front(std::string(mentry->mnt_dir));
560         }
561     }
562     endmntent(fp);
563
564     for (const auto& path : toUnmount) {
565         if (umount2(path.c_str(), MNT_DETACH)) {
566             ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
567         }
568     }
569     return 0;
570 }
571
572 int VolumeManager::remountUid(uid_t uid, const std::string& mode) {
573     LOG(DEBUG) << "Remounting " << uid << " as mode " << mode;
574
575     DIR* dir;
576     struct dirent* de;
577     char rootName[PATH_MAX];
578     char pidName[PATH_MAX];
579     int pidFd;
580     int nsFd;
581     struct stat sb;
582     pid_t child;
583
584     if (!(dir = opendir("/proc"))) {
585         PLOG(ERROR) << "Failed to opendir";
586         return -1;
587     }
588
589     // Figure out root namespace to compare against below
590     if (android::vold::SaneReadLinkAt(dirfd(dir), "1/ns/mnt", rootName, PATH_MAX) == -1) {
591         PLOG(ERROR) << "Failed to readlink";
592         closedir(dir);
593         return -1;
594     }
595
596     // Poke through all running PIDs look for apps running as UID
597     while ((de = readdir(dir))) {
598         pidFd = -1;
599         nsFd = -1;
600
601         pidFd = openat(dirfd(dir), de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
602         if (pidFd < 0) {
603             goto next;
604         }
605         if (fstat(pidFd, &sb) != 0) {
606             PLOG(WARNING) << "Failed to stat " << de->d_name;
607             goto next;
608         }
609         if (sb.st_uid != uid) {
610             goto next;
611         }
612
613         // Matches so far, but refuse to touch if in root namespace
614         LOG(DEBUG) << "Found matching PID " << de->d_name;
615         if (android::vold::SaneReadLinkAt(pidFd, "ns/mnt", pidName, PATH_MAX) == -1) {
616             PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
617             goto next;
618         }
619         if (!strcmp(rootName, pidName)) {
620             LOG(WARNING) << "Skipping due to root namespace";
621             goto next;
622         }
623
624         // We purposefully leave the namespace open across the fork
625         nsFd = openat(pidFd, "ns/mnt", O_RDONLY); // not O_CLOEXEC
626         if (nsFd < 0) {
627             PLOG(WARNING) << "Failed to open namespace for " << de->d_name;
628             goto next;
629         }
630
631         if (!(child = fork())) {
632             if (setns(nsFd, CLONE_NEWNS) != 0) {
633                 PLOG(ERROR) << "Failed to setns for " << de->d_name;
634                 _exit(1);
635             }
636
637             unmount_tree("/storage");
638
639             std::string storageSource;
640             if (mode == "default") {
641                 storageSource = "/mnt/runtime/default";
642             } else if (mode == "read") {
643                 storageSource = "/mnt/runtime/read";
644             } else if (mode == "write") {
645                 storageSource = "/mnt/runtime/write";
646             } else {
647                 // Sane default of no storage visible
648                 _exit(0);
649             }
650             if (TEMP_FAILURE_RETRY(mount(storageSource.c_str(), "/storage",
651                     NULL, MS_BIND | MS_REC, NULL)) == -1) {
652                 PLOG(ERROR) << "Failed to mount " << storageSource << " for "
653                         << de->d_name;
654                 _exit(1);
655             }
656             if (TEMP_FAILURE_RETRY(mount(NULL, "/storage", NULL,
657                     MS_REC | MS_SLAVE, NULL)) == -1) {
658                 PLOG(ERROR) << "Failed to set MS_SLAVE to /storage for "
659                         << de->d_name;
660                 _exit(1);
661             }
662
663             // Mount user-specific symlink helper into place
664             userid_t user_id = multiuser_get_user_id(uid);
665             std::string userSource(StringPrintf("/mnt/user/%d", user_id));
666             if (TEMP_FAILURE_RETRY(mount(userSource.c_str(), "/storage/self",
667                     NULL, MS_BIND, NULL)) == -1) {
668                 PLOG(ERROR) << "Failed to mount " << userSource << " for "
669                         << de->d_name;
670                 _exit(1);
671             }
672
673             _exit(0);
674         }
675
676         if (child == -1) {
677             PLOG(ERROR) << "Failed to fork";
678             goto next;
679         } else {
680             TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
681         }
682
683 next:
684         close(nsFd);
685         close(pidFd);
686     }
687     closedir(dir);
688     return 0;
689 }
690
691 int VolumeManager::reset() {
692     // Tear down all existing disks/volumes and start from a blank slate so
693     // newly connected framework hears all events.
694     mInternalEmulated->destroy();
695     mInternalEmulated->create();
696     for (const auto& disk : mDisks) {
697         disk->destroy();
698         disk->create();
699     }
700     updateVirtualDisk();
701     mAddedUsers.clear();
702     mStartedUsers.clear();
703     return 0;
704 }
705
706 // Can be called twice (sequentially) during shutdown. should be safe for that.
707 int VolumeManager::shutdown() {
708     if (mInternalEmulated == nullptr) {
709         return 0; // already shutdown
710     }
711     mInternalEmulated->destroy();
712     mInternalEmulated = nullptr;
713     for (const auto& disk : mDisks) {
714         disk->destroy();
715     }
716     mDisks.clear();
717     return 0;
718 }
719
720 int VolumeManager::unmountAll() {
721     std::lock_guard<std::mutex> lock(mLock);
722
723     // First, try gracefully unmounting all known devices
724     if (mInternalEmulated != nullptr) {
725         mInternalEmulated->unmount();
726     }
727     for (const auto& disk : mDisks) {
728         disk->unmountAll();
729     }
730
731     // Worst case we might have some stale mounts lurking around, so
732     // force unmount those just to be safe.
733     FILE* fp = setmntent("/proc/mounts", "r");
734     if (fp == NULL) {
735         SLOGE("Error opening /proc/mounts: %s", strerror(errno));
736         return -errno;
737     }
738
739     // Some volumes can be stacked on each other, so force unmount in
740     // reverse order to give us the best chance of success.
741     std::list<std::string> toUnmount;
742     mntent* mentry;
743     while ((mentry = getmntent(fp)) != NULL) {
744         if (strncmp(mentry->mnt_dir, "/mnt/", 5) == 0
745                 || strncmp(mentry->mnt_dir, "/storage/", 9) == 0) {
746             toUnmount.push_front(std::string(mentry->mnt_dir));
747         }
748     }
749     endmntent(fp);
750
751     for (const auto& path : toUnmount) {
752         SLOGW("Tearing down stale mount %s", path.c_str());
753         android::vold::ForceUnmount(path);
754     }
755
756     return 0;
757 }
758
759 int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) {
760     char idHash[33];
761     if (!asecHash(sourceFile, idHash, sizeof(idHash))) {
762         SLOGE("Hash of '%s' failed (%s)", sourceFile, strerror(errno));
763         return -1;
764     }
765
766     memset(mountPath, 0, mountPathLen);
767     int written = snprintf(mountPath, mountPathLen, "%s/%s", VolumeManager::LOOPDIR, idHash);
768     if ((written < 0) || (written >= mountPathLen)) {
769         errno = EINVAL;
770         return -1;
771     }
772
773     if (access(mountPath, F_OK)) {
774         errno = ENOENT;
775         return -1;
776     }
777
778     return 0;
779 }
780
781 int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
782     char asecFileName[255];
783
784     if (!isLegalAsecId(id)) {
785         SLOGE("getAsecMountPath: Invalid asec id \"%s\"", id);
786         errno = EINVAL;
787         return -1;
788     }
789
790     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
791         SLOGE("Couldn't find ASEC %s", id);
792         return -1;
793     }
794
795     memset(buffer, 0, maxlen);
796     if (access(asecFileName, F_OK)) {
797         errno = ENOENT;
798         return -1;
799     }
800
801     int written = snprintf(buffer, maxlen, "%s/%s", VolumeManager::ASECDIR, id);
802     if ((written < 0) || (written >= maxlen)) {
803         SLOGE("getAsecMountPath failed for %s: couldn't construct path in buffer", id);
804         errno = EINVAL;
805         return -1;
806     }
807
808     return 0;
809 }
810
811 int VolumeManager::getAsecFilesystemPath(const char *id, char *buffer, int maxlen) {
812     char asecFileName[255];
813
814     if (!isLegalAsecId(id)) {
815         SLOGE("getAsecFilesystemPath: Invalid asec id \"%s\"", id);
816         errno = EINVAL;
817         return -1;
818     }
819
820     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
821         SLOGE("Couldn't find ASEC %s", id);
822         return -1;
823     }
824
825     memset(buffer, 0, maxlen);
826     if (access(asecFileName, F_OK)) {
827         errno = ENOENT;
828         return -1;
829     }
830
831     int written = snprintf(buffer, maxlen, "%s", asecFileName);
832     if ((written < 0) || (written >= maxlen)) {
833         errno = EINVAL;
834         return -1;
835     }
836
837     return 0;
838 }
839
840 int VolumeManager::createAsec(const char *id, unsigned long numSectors, const char *fstype,
841         const char *key, const int ownerUid, bool isExternal) {
842     struct asec_superblock sb;
843     memset(&sb, 0, sizeof(sb));
844
845     if (!isLegalAsecId(id)) {
846         SLOGE("createAsec: Invalid asec id \"%s\"", id);
847         errno = EINVAL;
848         return -1;
849     }
850
851     const bool wantFilesystem = strcmp(fstype, "none");
852     bool usingExt4 = false;
853     if (wantFilesystem) {
854         usingExt4 = !strcmp(fstype, "ext4");
855         if (usingExt4) {
856             sb.c_opts |= ASEC_SB_C_OPTS_EXT4;
857         } else if (strcmp(fstype, "fat")) {
858             SLOGE("Invalid filesystem type %s", fstype);
859             errno = EINVAL;
860             return -1;
861         }
862     }
863
864     sb.magic = ASEC_SB_MAGIC;
865     sb.ver = ASEC_SB_VER;
866
867     if (numSectors < ((1024*1024)/512)) {
868         SLOGE("Invalid container size specified (%lu sectors)", numSectors);
869         errno = EINVAL;
870         return -1;
871     }
872
873     char asecFileName[255];
874
875     if (!findAsec(id, asecFileName, sizeof(asecFileName))) {
876         SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)",
877                 asecFileName, strerror(errno));
878         errno = EADDRINUSE;
879         return -1;
880     }
881
882     const char *asecDir = isExternal ? VolumeManager::SEC_ASECDIR_EXT : VolumeManager::SEC_ASECDIR_INT;
883
884     int written = snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", asecDir, id);
885     if ((written < 0) || (size_t(written) >= sizeof(asecFileName))) {
886         errno = EINVAL;
887         return -1;
888     }
889
890     if (!access(asecFileName, F_OK)) {
891         SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)",
892                 asecFileName, strerror(errno));
893         errno = EADDRINUSE;
894         return -1;
895     }
896
897     unsigned long numImgSectors;
898     if (usingExt4)
899         numImgSectors = adjustSectorNumExt4(numSectors);
900     else
901         numImgSectors = adjustSectorNumFAT(numSectors);
902
903     // Add +1 for our superblock which is at the end
904     if (Loop::createImageFile(asecFileName, numImgSectors + 1)) {
905         SLOGE("ASEC image file creation failed (%s)", strerror(errno));
906         return -1;
907     }
908
909     char idHash[33];
910     if (!asecHash(id, idHash, sizeof(idHash))) {
911         SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
912         unlink(asecFileName);
913         return -1;
914     }
915
916     char loopDevice[255];
917     if (Loop::create(idHash, asecFileName, loopDevice, sizeof(loopDevice))) {
918         SLOGE("ASEC loop device creation failed (%s)", strerror(errno));
919         unlink(asecFileName);
920         return -1;
921     }
922
923     char dmDevice[255];
924     bool cleanupDm = false;
925
926     if (strcmp(key, "none")) {
927         // XXX: This is all we support for now
928         sb.c_cipher = ASEC_SB_C_CIPHER_TWOFISH;
929         if (Devmapper::create(idHash, loopDevice, key, numImgSectors, dmDevice,
930                              sizeof(dmDevice))) {
931             SLOGE("ASEC device mapping failed (%s)", strerror(errno));
932             Loop::destroyByDevice(loopDevice);
933             unlink(asecFileName);
934             return -1;
935         }
936         cleanupDm = true;
937     } else {
938         sb.c_cipher = ASEC_SB_C_CIPHER_NONE;
939         strcpy(dmDevice, loopDevice);
940     }
941
942     /*
943      * Drop down the superblock at the end of the file
944      */
945     if (writeSuperBlock(loopDevice, &sb, numImgSectors)) {
946         if (cleanupDm) {
947             Devmapper::destroy(idHash);
948         }
949         Loop::destroyByDevice(loopDevice);
950         unlink(asecFileName);
951         return -1;
952     }
953
954     if (wantFilesystem) {
955         int formatStatus;
956         char mountPoint[255];
957
958         int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
959         if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
960             SLOGE("ASEC fs format failed: couldn't construct mountPoint");
961             if (cleanupDm) {
962                 Devmapper::destroy(idHash);
963             }
964             Loop::destroyByDevice(loopDevice);
965             unlink(asecFileName);
966             return -1;
967         }
968
969         if (usingExt4) {
970             formatStatus = android::vold::ext4::Format(dmDevice, numImgSectors, mountPoint);
971         } else {
972             formatStatus = android::vold::vfat::Format(dmDevice, numImgSectors);
973         }
974
975         if (formatStatus < 0) {
976             SLOGE("ASEC fs format failed (%s)", strerror(errno));
977             if (cleanupDm) {
978                 Devmapper::destroy(idHash);
979             }
980             Loop::destroyByDevice(loopDevice);
981             unlink(asecFileName);
982             return -1;
983         }
984
985         if (mkdir(mountPoint, 0000)) {
986             if (errno != EEXIST) {
987                 SLOGE("Mountpoint creation failed (%s)", strerror(errno));
988                 if (cleanupDm) {
989                     Devmapper::destroy(idHash);
990                 }
991                 Loop::destroyByDevice(loopDevice);
992                 unlink(asecFileName);
993                 return -1;
994             }
995         }
996
997         int mountStatus;
998         if (usingExt4) {
999             mountStatus = android::vold::ext4::Mount(dmDevice, mountPoint,
1000                     false, false, false);
1001         } else {
1002             mountStatus = android::vold::vfat::Mount(dmDevice, mountPoint,
1003                     false, false, false, ownerUid, 0, 0000, false);
1004         }
1005
1006         if (mountStatus) {
1007             SLOGE("ASEC FAT mount failed (%s)", strerror(errno));
1008             if (cleanupDm) {
1009                 Devmapper::destroy(idHash);
1010             }
1011             Loop::destroyByDevice(loopDevice);
1012             unlink(asecFileName);
1013             return -1;
1014         }
1015
1016         if (usingExt4) {
1017             int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
1018             if (dirfd >= 0) {
1019                 if (fchown(dirfd, ownerUid, AID_SYSTEM)
1020                         || fchmod(dirfd, S_IRUSR | S_IWUSR | S_IXUSR | S_ISGID | S_IRGRP | S_IXGRP)) {
1021                     SLOGI("Cannot chown/chmod new ASEC mount point %s", mountPoint);
1022                 }
1023                 close(dirfd);
1024             }
1025         }
1026     } else {
1027         SLOGI("Created raw secure container %s (no filesystem)", id);
1028     }
1029
1030     mActiveContainers->push_back(new ContainerData(strdup(id), ASEC));
1031     return 0;
1032 }
1033
1034 int VolumeManager::resizeAsec(const char *id, unsigned long numSectors, const char *key) {
1035     char asecFileName[255];
1036     char mountPoint[255];
1037     bool cleanupDm = false;
1038
1039     if (!isLegalAsecId(id)) {
1040         SLOGE("resizeAsec: Invalid asec id \"%s\"", id);
1041         errno = EINVAL;
1042         return -1;
1043     }
1044
1045     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
1046         SLOGE("Couldn't find ASEC %s", id);
1047         return -1;
1048     }
1049
1050     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
1051     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1052        SLOGE("ASEC resize failed for %s: couldn't construct mountpoint", id);
1053        return -1;
1054     }
1055
1056     if (isMountpointMounted(mountPoint)) {
1057        SLOGE("ASEC %s mounted. Unmount before resizing", id);
1058        errno = EBUSY;
1059        return -1;
1060     }
1061
1062     struct asec_superblock sb;
1063     int fd;
1064     unsigned long oldNumSec = 0;
1065
1066     if ((fd = open(asecFileName, O_RDONLY | O_CLOEXEC)) < 0) {
1067         SLOGE("Failed to open ASEC file (%s)", strerror(errno));
1068         return -1;
1069     }
1070
1071     struct stat info;
1072     if (fstat(fd, &info) < 0) {
1073         SLOGE("Failed to get file size (%s)", strerror(errno));
1074         close(fd);
1075         return -1;
1076     }
1077
1078     oldNumSec = info.st_size / 512;
1079
1080     /*
1081      * Try to read superblock.
1082      */
1083     memset(&sb, 0, sizeof(struct asec_superblock));
1084     if (lseek(fd, ((oldNumSec - 1) * 512), SEEK_SET) < 0) {
1085         SLOGE("lseek failed (%s)", strerror(errno));
1086         close(fd);
1087         return -1;
1088     }
1089     if (read(fd, &sb, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
1090         SLOGE("superblock read failed (%s)", strerror(errno));
1091         close(fd);
1092         return -1;
1093     }
1094     close(fd);
1095
1096     if (mDebug) {
1097         SLOGD("Container sb magic/ver (%.8x/%.2x)", sb.magic, sb.ver);
1098     }
1099     if (sb.magic != ASEC_SB_MAGIC || sb.ver != ASEC_SB_VER) {
1100         SLOGE("Bad container magic/version (%.8x/%.2x)", sb.magic, sb.ver);
1101         errno = EMEDIUMTYPE;
1102         return -1;
1103     }
1104
1105     unsigned long numImgSectors;
1106     if (!(sb.c_opts & ASEC_SB_C_OPTS_EXT4)) {
1107         SLOGE("Only ext4 partitions are supported for resize");
1108         errno = EINVAL;
1109         return -1;
1110     } else {
1111         numImgSectors = adjustSectorNumExt4(numSectors);
1112     }
1113
1114     /*
1115      *  add one block for the superblock
1116      */
1117     SLOGD("Resizing from %lu sectors to %lu sectors", oldNumSec, numImgSectors + 1);
1118     if (oldNumSec == numImgSectors + 1) {
1119         SLOGW("Size unchanged; ignoring resize request");
1120         return 0;
1121     } else if (oldNumSec > numImgSectors + 1) {
1122         SLOGE("Only growing is currently supported.");
1123         close(fd);
1124         return -1;
1125     }
1126
1127     if (Loop::resizeImageFile(asecFileName, numImgSectors + 1)) {
1128         SLOGE("Resize of ASEC image file failed. Could not resize %s", id);
1129         return -1;
1130     }
1131
1132     /*
1133      * Drop down a copy of the superblock at the end of the file
1134      */
1135     if (writeSuperBlock(asecFileName, &sb, numImgSectors))
1136         goto fail;
1137
1138     char idHash[33];
1139     if (!asecHash(id, idHash, sizeof(idHash))) {
1140         SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
1141         goto fail;
1142     }
1143
1144     char loopDevice[255];
1145     if (setupLoopDevice(loopDevice, sizeof(loopDevice), asecFileName, idHash, mDebug))
1146         goto fail;
1147
1148     char dmDevice[255];
1149
1150     if (setupDevMapperDevice(dmDevice, sizeof(dmDevice), loopDevice, asecFileName, key, idHash, numImgSectors, &cleanupDm, mDebug)) {
1151         Loop::destroyByDevice(loopDevice);
1152         goto fail;
1153     }
1154
1155     /*
1156      * Wait for the device mapper node to be created.
1157      */
1158     waitForDevMapper(dmDevice);
1159
1160     if (android::vold::ext4::Resize(dmDevice, numImgSectors)) {
1161         SLOGE("Unable to resize %s (%s)", id, strerror(errno));
1162         if (cleanupDm) {
1163             Devmapper::destroy(idHash);
1164         }
1165         Loop::destroyByDevice(loopDevice);
1166         goto fail;
1167     }
1168
1169     return 0;
1170 fail:
1171     Loop::resizeImageFile(asecFileName, oldNumSec);
1172     return -1;
1173 }
1174
1175 int VolumeManager::finalizeAsec(const char *id) {
1176     char asecFileName[255];
1177     char loopDevice[255];
1178     char mountPoint[255];
1179
1180     if (!isLegalAsecId(id)) {
1181         SLOGE("finalizeAsec: Invalid asec id \"%s\"", id);
1182         errno = EINVAL;
1183         return -1;
1184     }
1185
1186     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
1187         SLOGE("Couldn't find ASEC %s", id);
1188         return -1;
1189     }
1190
1191     char idHash[33];
1192     if (!asecHash(id, idHash, sizeof(idHash))) {
1193         SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
1194         return -1;
1195     }
1196
1197     if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) {
1198         SLOGE("Unable to finalize %s (%s)", id, strerror(errno));
1199         return -1;
1200     }
1201
1202     unsigned long nr_sec = 0;
1203     struct asec_superblock sb;
1204
1205     if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) {
1206         return -1;
1207     }
1208
1209     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
1210     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1211         SLOGE("ASEC finalize failed: couldn't construct mountPoint");
1212         return -1;
1213     }
1214
1215     int result = 0;
1216     if (sb.c_opts & ASEC_SB_C_OPTS_EXT4) {
1217         result = android::vold::ext4::Mount(loopDevice, mountPoint,
1218                 true, true, true);
1219     } else {
1220         result = android::vold::vfat::Mount(loopDevice, mountPoint,
1221                 true, true, true, 0, 0, 0227, false);
1222     }
1223
1224     if (result) {
1225         SLOGE("ASEC finalize mount failed (%s)", strerror(errno));
1226         return -1;
1227     }
1228
1229     if (mDebug) {
1230         SLOGD("ASEC %s finalized", id);
1231     }
1232     return 0;
1233 }
1234
1235 int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* filename) {
1236     char asecFileName[255];
1237     char loopDevice[255];
1238     char mountPoint[255];
1239
1240     if (gid < AID_APP) {
1241         SLOGE("Group ID is not in application range");
1242         return -1;
1243     }
1244
1245     if (!isLegalAsecId(id)) {
1246         SLOGE("fixupAsecPermissions: Invalid asec id \"%s\"", id);
1247         errno = EINVAL;
1248         return -1;
1249     }
1250
1251     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
1252         SLOGE("Couldn't find ASEC %s", id);
1253         return -1;
1254     }
1255
1256     char idHash[33];
1257     if (!asecHash(id, idHash, sizeof(idHash))) {
1258         SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
1259         return -1;
1260     }
1261
1262     if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) {
1263         SLOGE("Unable fix permissions during lookup on %s (%s)", id, strerror(errno));
1264         return -1;
1265     }
1266
1267     unsigned long nr_sec = 0;
1268     struct asec_superblock sb;
1269
1270     if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) {
1271         return -1;
1272     }
1273
1274     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
1275     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1276         SLOGE("Unable remount to fix permissions for %s: couldn't construct mountpoint", id);
1277         return -1;
1278     }
1279
1280     int result = 0;
1281     if ((sb.c_opts & ASEC_SB_C_OPTS_EXT4) == 0) {
1282         return 0;
1283     }
1284
1285     int ret = android::vold::ext4::Mount(loopDevice, mountPoint,
1286             false /* read-only */,
1287             true  /* remount */,
1288             false /* executable */);
1289     if (ret) {
1290         SLOGE("Unable remount to fix permissions for %s (%s)", id, strerror(errno));
1291         return -1;
1292     }
1293
1294     char *paths[] = { mountPoint, NULL };
1295
1296     FTS *fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL);
1297     if (fts) {
1298         // Traverse the entire hierarchy and chown to system UID.
1299         for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) {
1300             // We don't care about the lost+found directory.
1301             if (!strcmp(ftsent->fts_name, "lost+found")) {
1302                 continue;
1303             }
1304
1305             /*
1306              * There can only be one file marked as private right now.
1307              * This should be more robust, but it satisfies the requirements
1308              * we have for right now.
1309              */
1310             const bool privateFile = !strcmp(ftsent->fts_name, filename);
1311
1312             int fd = open(ftsent->fts_accpath, O_NOFOLLOW | O_CLOEXEC);
1313             if (fd < 0) {
1314                 SLOGE("Couldn't open file %s: %s", ftsent->fts_accpath, strerror(errno));
1315                 result = -1;
1316                 continue;
1317             }
1318
1319             result |= fchown(fd, AID_SYSTEM, privateFile? gid : AID_SYSTEM);
1320
1321             if (ftsent->fts_info & FTS_D) {
1322                 result |= fchmod(fd, 0755);
1323             } else if (ftsent->fts_info & FTS_F) {
1324                 result |= fchmod(fd, privateFile ? 0640 : 0644);
1325             }
1326
1327             if (selinux_android_restorecon(ftsent->fts_path, 0) < 0) {
1328                 SLOGE("restorecon failed for %s: %s\n", ftsent->fts_path, strerror(errno));
1329                 result |= -1;
1330             }
1331
1332             close(fd);
1333         }
1334         fts_close(fts);
1335
1336         // Finally make the directory readable by everyone.
1337         int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
1338         if (dirfd < 0 || fchmod(dirfd, 0755)) {
1339             SLOGE("Couldn't change owner of existing directory %s: %s", mountPoint, strerror(errno));
1340             result |= -1;
1341         }
1342         close(dirfd);
1343     } else {
1344         result |= -1;
1345     }
1346
1347     result |= android::vold::ext4::Mount(loopDevice, mountPoint,
1348             true /* read-only */,
1349             true /* remount */,
1350             true /* execute */);
1351
1352     if (result) {
1353         SLOGE("ASEC fix permissions failed (%s)", strerror(errno));
1354         return -1;
1355     }
1356
1357     if (mDebug) {
1358         SLOGD("ASEC %s permissions fixed", id);
1359     }
1360     return 0;
1361 }
1362
1363 int VolumeManager::renameAsec(const char *id1, const char *id2) {
1364     char asecFilename1[255];
1365     char *asecFilename2;
1366     char mountPoint[255];
1367
1368     const char *dir;
1369
1370     if (!isLegalAsecId(id1)) {
1371         SLOGE("renameAsec: Invalid asec id1 \"%s\"", id1);
1372         errno = EINVAL;
1373         return -1;
1374     }
1375
1376     if (!isLegalAsecId(id2)) {
1377         SLOGE("renameAsec: Invalid asec id2 \"%s\"", id2);
1378         errno = EINVAL;
1379         return -1;
1380     }
1381
1382     if (findAsec(id1, asecFilename1, sizeof(asecFilename1), &dir)) {
1383         SLOGE("Couldn't find ASEC %s", id1);
1384         return -1;
1385     }
1386
1387     asprintf(&asecFilename2, "%s/%s.asec", dir, id2);
1388
1389     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id1);
1390     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1391         SLOGE("Rename failed: couldn't construct mountpoint");
1392         goto out_err;
1393     }
1394
1395     if (isMountpointMounted(mountPoint)) {
1396         SLOGW("Rename attempt when src mounted");
1397         errno = EBUSY;
1398         goto out_err;
1399     }
1400
1401     written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id2);
1402     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1403         SLOGE("Rename failed: couldn't construct mountpoint2");
1404         goto out_err;
1405     }
1406
1407     if (isMountpointMounted(mountPoint)) {
1408         SLOGW("Rename attempt when dst mounted");
1409         errno = EBUSY;
1410         goto out_err;
1411     }
1412
1413     if (!access(asecFilename2, F_OK)) {
1414         SLOGE("Rename attempt when dst exists");
1415         errno = EADDRINUSE;
1416         goto out_err;
1417     }
1418
1419     if (rename(asecFilename1, asecFilename2)) {
1420         SLOGE("Rename of '%s' to '%s' failed (%s)", asecFilename1, asecFilename2, strerror(errno));
1421         goto out_err;
1422     }
1423
1424     free(asecFilename2);
1425     return 0;
1426
1427 out_err:
1428     free(asecFilename2);
1429     return -1;
1430 }
1431
1432 #define UNMOUNT_RETRIES 5
1433 #define UNMOUNT_SLEEP_BETWEEN_RETRY_MS (1000 * 1000)
1434 int VolumeManager::unmountAsec(const char *id, bool force) {
1435     char asecFileName[255];
1436     char mountPoint[255];
1437
1438     if (!isLegalAsecId(id)) {
1439         SLOGE("unmountAsec: Invalid asec id \"%s\"", id);
1440         errno = EINVAL;
1441         return -1;
1442     }
1443
1444     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
1445         SLOGE("Couldn't find ASEC %s", id);
1446         return -1;
1447     }
1448
1449     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
1450     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1451         SLOGE("ASEC unmount failed for %s: couldn't construct mountpoint", id);
1452         return -1;
1453     }
1454
1455     char idHash[33];
1456     if (!asecHash(id, idHash, sizeof(idHash))) {
1457         SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
1458         return -1;
1459     }
1460
1461     return unmountLoopImage(id, idHash, asecFileName, mountPoint, force);
1462 }
1463
1464 int VolumeManager::unmountObb(const char *fileName, bool force) {
1465     char mountPoint[255];
1466
1467     char idHash[33];
1468     if (!asecHash(fileName, idHash, sizeof(idHash))) {
1469         SLOGE("Hash of '%s' failed (%s)", fileName, strerror(errno));
1470         return -1;
1471     }
1472
1473     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
1474     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1475         SLOGE("OBB unmount failed for %s: couldn't construct mountpoint", fileName);
1476         return -1;
1477     }
1478
1479     return unmountLoopImage(fileName, idHash, fileName, mountPoint, force);
1480 }
1481
1482 int VolumeManager::unmountLoopImage(const char *id, const char *idHash,
1483         const char *fileName, const char *mountPoint, bool force) {
1484     if (!isMountpointMounted(mountPoint)) {
1485         SLOGE("Unmount request for %s when not mounted", id);
1486         errno = ENOENT;
1487         return -1;
1488     }
1489
1490     int i, rc;
1491     for (i = 1; i <= UNMOUNT_RETRIES; i++) {
1492         rc = umount(mountPoint);
1493         if (!rc) {
1494             break;
1495         }
1496         if (rc && (errno == EINVAL || errno == ENOENT)) {
1497             SLOGI("Container %s unmounted OK", id);
1498             rc = 0;
1499             break;
1500         }
1501         SLOGW("%s unmount attempt %d failed (%s)",
1502               id, i, strerror(errno));
1503
1504         int signal = 0; // default is to just complain
1505
1506         if (force) {
1507             if (i > (UNMOUNT_RETRIES - 2))
1508                 signal = SIGKILL;
1509             else if (i > (UNMOUNT_RETRIES - 3))
1510                 signal = SIGTERM;
1511         }
1512
1513         Process::killProcessesWithOpenFiles(mountPoint, signal);
1514         usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
1515     }
1516
1517     if (rc) {
1518         errno = EBUSY;
1519         SLOGE("Failed to unmount container %s (%s)", id, strerror(errno));
1520         return -1;
1521     }
1522
1523     int retries = 10;
1524
1525     while(retries--) {
1526         if (!rmdir(mountPoint)) {
1527             break;
1528         }
1529
1530         SLOGW("Failed to rmdir %s (%s)", mountPoint, strerror(errno));
1531         usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
1532     }
1533
1534     if (!retries) {
1535         SLOGE("Timed out trying to rmdir %s (%s)", mountPoint, strerror(errno));
1536     }
1537
1538     for (i=1; i <= UNMOUNT_RETRIES; i++) {
1539         if (Devmapper::destroy(idHash) && errno != ENXIO) {
1540             SLOGE("Failed to destroy devmapper instance (%s)", strerror(errno));
1541             usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
1542             continue;
1543         } else {
1544           break;
1545         }
1546     }
1547
1548     char loopDevice[255];
1549     if (!Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) {
1550         Loop::destroyByDevice(loopDevice);
1551     } else {
1552         SLOGW("Failed to find loop device for {%s} (%s)", fileName, strerror(errno));
1553     }
1554
1555     AsecIdCollection::iterator it;
1556     for (it = mActiveContainers->begin(); it != mActiveContainers->end(); ++it) {
1557         ContainerData* cd = *it;
1558         if (!strcmp(cd->id, id)) {
1559             free(*it);
1560             mActiveContainers->erase(it);
1561             break;
1562         }
1563     }
1564     if (it == mActiveContainers->end()) {
1565         SLOGW("mActiveContainers is inconsistent!");
1566     }
1567     return 0;
1568 }
1569
1570 int VolumeManager::destroyAsec(const char *id, bool force) {
1571     char asecFileName[255];
1572     char mountPoint[255];
1573
1574     if (!isLegalAsecId(id)) {
1575         SLOGE("destroyAsec: Invalid asec id \"%s\"", id);
1576         errno = EINVAL;
1577         return -1;
1578     }
1579
1580     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
1581         SLOGE("Couldn't find ASEC %s", id);
1582         return -1;
1583     }
1584
1585     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
1586     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1587         SLOGE("ASEC destroy failed for %s: couldn't construct mountpoint", id);
1588         return -1;
1589     }
1590
1591     if (isMountpointMounted(mountPoint)) {
1592         if (mDebug) {
1593             SLOGD("Unmounting container before destroy");
1594         }
1595         if (unmountAsec(id, force)) {
1596             SLOGE("Failed to unmount asec %s for destroy (%s)", id, strerror(errno));
1597             return -1;
1598         }
1599     }
1600
1601     if (unlink(asecFileName)) {
1602         SLOGE("Failed to unlink asec '%s' (%s)", asecFileName, strerror(errno));
1603         return -1;
1604     }
1605
1606     if (mDebug) {
1607         SLOGD("ASEC %s destroyed", id);
1608     }
1609     return 0;
1610 }
1611
1612 /*
1613  * Legal ASEC ids consist of alphanumeric characters, '-',
1614  * '_', or '.'. ".." is not allowed. The first or last character
1615  * of the ASEC id cannot be '.' (dot).
1616  */
1617 bool VolumeManager::isLegalAsecId(const char *id) const {
1618     size_t i;
1619     size_t len = strlen(id);
1620
1621     if (len == 0) {
1622         return false;
1623     }
1624     if ((id[0] == '.') || (id[len - 1] == '.')) {
1625         return false;
1626     }
1627
1628     for (i = 0; i < len; i++) {
1629         if (id[i] == '.') {
1630             // i=0 is guaranteed never to have a dot. See above.
1631             if (id[i-1] == '.') return false;
1632             continue;
1633         }
1634         if (id[i] == '_' || id[i] == '-') continue;
1635         if (id[i] >= 'a' && id[i] <= 'z') continue;
1636         if (id[i] >= 'A' && id[i] <= 'Z') continue;
1637         if (id[i] >= '0' && id[i] <= '9') continue;
1638         return false;
1639     }
1640
1641     return true;
1642 }
1643
1644 bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const {
1645     int dirfd = open(dir, O_DIRECTORY | O_CLOEXEC);
1646     if (dirfd < 0) {
1647         SLOGE("Couldn't open internal ASEC dir (%s)", strerror(errno));
1648         return false;
1649     }
1650
1651     struct stat sb;
1652     bool ret = (fstatat(dirfd, asecName, &sb, AT_SYMLINK_NOFOLLOW) == 0)
1653         && S_ISREG(sb.st_mode);
1654
1655     close(dirfd);
1656
1657     return ret;
1658 }
1659
1660 int VolumeManager::findAsec(const char *id, char *asecPath, size_t asecPathLen,
1661         const char **directory) const {
1662     char *asecName;
1663
1664     if (!isLegalAsecId(id)) {
1665         SLOGE("findAsec: Invalid asec id \"%s\"", id);
1666         errno = EINVAL;
1667         return -1;
1668     }
1669
1670     if (asprintf(&asecName, "%s.asec", id) < 0) {
1671         SLOGE("Couldn't allocate string to write ASEC name");
1672         return -1;
1673     }
1674
1675     const char *dir;
1676     if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_INT, asecName)) {
1677         dir = VolumeManager::SEC_ASECDIR_INT;
1678     } else if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_EXT, asecName)) {
1679         dir = VolumeManager::SEC_ASECDIR_EXT;
1680     } else {
1681         free(asecName);
1682         return -1;
1683     }
1684
1685     if (directory != NULL) {
1686         *directory = dir;
1687     }
1688
1689     if (asecPath != NULL) {
1690         int written = snprintf(asecPath, asecPathLen, "%s/%s", dir, asecName);
1691         if ((written < 0) || (size_t(written) >= asecPathLen)) {
1692             SLOGE("findAsec failed for %s: couldn't construct ASEC path", id);
1693             free(asecName);
1694             return -1;
1695         }
1696     }
1697
1698     free(asecName);
1699     return 0;
1700 }
1701
1702 int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid, bool readOnly) {
1703     char asecFileName[255];
1704     char mountPoint[255];
1705
1706     if (!isLegalAsecId(id)) {
1707         SLOGE("mountAsec: Invalid asec id \"%s\"", id);
1708         errno = EINVAL;
1709         return -1;
1710     }
1711
1712     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
1713         SLOGE("Couldn't find ASEC %s", id);
1714         return -1;
1715     }
1716
1717     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
1718     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1719         SLOGE("ASEC mount failed for %s: couldn't construct mountpoint", id);
1720         return -1;
1721     }
1722
1723     if (isMountpointMounted(mountPoint)) {
1724         SLOGE("ASEC %s already mounted", id);
1725         errno = EBUSY;
1726         return -1;
1727     }
1728
1729     char idHash[33];
1730     if (!asecHash(id, idHash, sizeof(idHash))) {
1731         SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
1732         return -1;
1733     }
1734
1735     char loopDevice[255];
1736     if (setupLoopDevice(loopDevice, sizeof(loopDevice), asecFileName, idHash, mDebug))
1737         return -1;
1738
1739     char dmDevice[255];
1740     bool cleanupDm = false;
1741
1742     unsigned long nr_sec = 0;
1743     struct asec_superblock sb;
1744
1745     if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) {
1746         return -1;
1747     }
1748
1749     if (mDebug) {
1750         SLOGD("Container sb magic/ver (%.8x/%.2x)", sb.magic, sb.ver);
1751     }
1752     if (sb.magic != ASEC_SB_MAGIC || sb.ver != ASEC_SB_VER) {
1753         SLOGE("Bad container magic/version (%.8x/%.2x)", sb.magic, sb.ver);
1754         Loop::destroyByDevice(loopDevice);
1755         errno = EMEDIUMTYPE;
1756         return -1;
1757     }
1758     nr_sec--; // We don't want the devmapping to extend onto our superblock
1759
1760     if (setupDevMapperDevice(dmDevice, sizeof(dmDevice), loopDevice, asecFileName, key, idHash , nr_sec, &cleanupDm, mDebug)) {
1761         Loop::destroyByDevice(loopDevice);
1762         return -1;
1763     }
1764
1765     if (mkdir(mountPoint, 0000)) {
1766         if (errno != EEXIST) {
1767             SLOGE("Mountpoint creation failed (%s)", strerror(errno));
1768             if (cleanupDm) {
1769                 Devmapper::destroy(idHash);
1770             }
1771             Loop::destroyByDevice(loopDevice);
1772             return -1;
1773         }
1774     }
1775
1776     /*
1777      * Wait for the device mapper node to be created.
1778      */
1779     waitForDevMapper(dmDevice);
1780
1781     int result;
1782     if (sb.c_opts & ASEC_SB_C_OPTS_EXT4) {
1783         result = android::vold::ext4::Mount(dmDevice, mountPoint,
1784                 readOnly, false, readOnly);
1785     } else {
1786         result = android::vold::vfat::Mount(dmDevice, mountPoint,
1787                 readOnly, false, readOnly, ownerUid, 0, 0222, false);
1788     }
1789
1790     if (result) {
1791         SLOGE("ASEC mount failed (%s)", strerror(errno));
1792         if (cleanupDm) {
1793             Devmapper::destroy(idHash);
1794         }
1795         Loop::destroyByDevice(loopDevice);
1796         return -1;
1797     }
1798
1799     mActiveContainers->push_back(new ContainerData(strdup(id), ASEC));
1800     if (mDebug) {
1801         SLOGD("ASEC %s mounted", id);
1802     }
1803     return 0;
1804 }
1805
1806 /**
1807  * Mounts an image file <code>img</code>.
1808  */
1809 int VolumeManager::mountObb(const char *img, const char *key, int ownerGid) {
1810     char mountPoint[255];
1811
1812     char idHash[33];
1813     if (!asecHash(img, idHash, sizeof(idHash))) {
1814         SLOGE("Hash of '%s' failed (%s)", img, strerror(errno));
1815         return -1;
1816     }
1817
1818     int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
1819     if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
1820         SLOGE("OBB mount failed for %s: couldn't construct mountpoint", img);
1821         return -1;
1822     }
1823
1824     if (isMountpointMounted(mountPoint)) {
1825         SLOGE("Image %s already mounted", img);
1826         errno = EBUSY;
1827         return -1;
1828     }
1829
1830     char loopDevice[255];
1831     if (setupLoopDevice(loopDevice, sizeof(loopDevice), img, idHash, mDebug))
1832         return -1;
1833
1834     char dmDevice[255];
1835     bool cleanupDm = false;
1836     int fd;
1837     unsigned long nr_sec = 0;
1838
1839     if ((fd = open(loopDevice, O_RDWR | O_CLOEXEC)) < 0) {
1840         SLOGE("Failed to open loopdevice (%s)", strerror(errno));
1841         Loop::destroyByDevice(loopDevice);
1842         return -1;
1843     }
1844
1845     get_blkdev_size(fd, &nr_sec);
1846     if (nr_sec == 0) {
1847         SLOGE("Failed to get loop size (%s)", strerror(errno));
1848         Loop::destroyByDevice(loopDevice);
1849         close(fd);
1850         return -1;
1851     }
1852
1853     close(fd);
1854
1855     if (setupDevMapperDevice(dmDevice, sizeof(loopDevice), loopDevice, img,key, idHash, nr_sec, &cleanupDm, mDebug)) {
1856         Loop::destroyByDevice(loopDevice);
1857         return -1;
1858     }
1859
1860     if (mkdir(mountPoint, 0755)) {
1861         if (errno != EEXIST) {
1862             SLOGE("Mountpoint creation failed (%s)", strerror(errno));
1863             if (cleanupDm) {
1864                 Devmapper::destroy(idHash);
1865             }
1866             Loop::destroyByDevice(loopDevice);
1867             return -1;
1868         }
1869     }
1870
1871     /*
1872      * Wait for the device mapper node to be created.
1873      */
1874     waitForDevMapper(dmDevice);
1875
1876     if (android::vold::vfat::Mount(dmDevice, mountPoint,
1877             true, false, true, 0, ownerGid, 0227, false)) {
1878         SLOGE("Image mount failed (%s)", strerror(errno));
1879         if (cleanupDm) {
1880             Devmapper::destroy(idHash);
1881         }
1882         Loop::destroyByDevice(loopDevice);
1883         return -1;
1884     }
1885
1886     mActiveContainers->push_back(new ContainerData(strdup(img), OBB));
1887     if (mDebug) {
1888         SLOGD("Image %s mounted", img);
1889     }
1890     return 0;
1891 }
1892
1893 int VolumeManager::listMountedObbs(SocketClient* cli) {
1894     FILE *fp = setmntent("/proc/mounts", "r");
1895     if (fp == NULL) {
1896         SLOGE("Error opening /proc/mounts (%s)", strerror(errno));
1897         return -1;
1898     }
1899
1900     // Create a string to compare against that has a trailing slash
1901     int loopDirLen = strlen(VolumeManager::LOOPDIR);
1902     char loopDir[loopDirLen + 2];
1903     strcpy(loopDir, VolumeManager::LOOPDIR);
1904     loopDir[loopDirLen++] = '/';
1905     loopDir[loopDirLen] = '\0';
1906
1907     mntent* mentry;
1908     while ((mentry = getmntent(fp)) != NULL) {
1909         if (!strncmp(mentry->mnt_dir, loopDir, loopDirLen)) {
1910             int fd = open(mentry->mnt_fsname, O_RDONLY | O_CLOEXEC);
1911             if (fd >= 0) {
1912                 struct loop_info64 li;
1913                 if (ioctl(fd, LOOP_GET_STATUS64, &li) >= 0) {
1914                     cli->sendMsg(ResponseCode::AsecListResult,
1915                             (const char*) li.lo_file_name, false);
1916                 }
1917                 close(fd);
1918             }
1919         }
1920     }
1921     endmntent(fp);
1922     return 0;
1923 }
1924
1925 extern "C" int vold_unmountAll(void) {
1926     VolumeManager *vm = VolumeManager::Instance();
1927     return vm->unmountAll();
1928 }
1929
1930 bool VolumeManager::isMountpointMounted(const char *mp)
1931 {
1932     FILE *fp = setmntent("/proc/mounts", "r");
1933     if (fp == NULL) {
1934         SLOGE("Error opening /proc/mounts (%s)", strerror(errno));
1935         return false;
1936     }
1937
1938     bool found_mp = false;
1939     mntent* mentry;
1940     while ((mentry = getmntent(fp)) != NULL) {
1941         if (strcmp(mentry->mnt_dir, mp) == 0) {
1942             found_mp = true;
1943             break;
1944         }
1945     }
1946     endmntent(fp);
1947     return found_mp;
1948 }
1949
1950 int VolumeManager::mkdirs(char* path) {
1951     // Only offer to create directories for paths managed by vold
1952     if (strncmp(path, "/storage/", 9) == 0) {
1953         // fs_mkdirs() does symlink checking and relative path enforcement
1954         return fs_mkdirs(path, 0700);
1955     } else {
1956         SLOGE("Failed to find mounted volume for %s", path);
1957         return -EINVAL;
1958     }
1959 }