OSDN Git Service

Merge "Add noatime to vfat and exfat" into oc-mr1-dev
[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/sysmacros.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32
33 #include <linux/kdev_t.h>
34
35 #define LOG_TAG "Vold"
36
37 #include <openssl/md5.h>
38
39 #include <android-base/logging.h>
40 #include <android-base/stringprintf.h>
41 #include <cutils/fs.h>
42 #include <cutils/log.h>
43
44 #include <selinux/android.h>
45
46 #include <sysutils/NetlinkEvent.h>
47
48 #include <private/android_filesystem_config.h>
49
50 #include "Benchmark.h"
51 #include "EmulatedVolume.h"
52 #include "VolumeManager.h"
53 #include "NetlinkManager.h"
54 #include "ResponseCode.h"
55 #include "Loop.h"
56 #include "fs/Ext4.h"
57 #include "fs/Vfat.h"
58 #include "Utils.h"
59 #include "Devmapper.h"
60 #include "Process.h"
61 #include "Asec.h"
62 #include "VoldUtil.h"
63 #include "cryptfs.h"
64
65 #define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
66
67 #define ROUND_UP_POWER_OF_2(number, po2) (((!!((number) & ((1U << (po2)) - 1))) << (po2))\
68                                          + ((number) & (~((1U << (po2)) - 1))))
69
70 using android::base::StringPrintf;
71
72 /*
73  * Path to external storage where *only* root can access ASEC image files
74  */
75 const char *VolumeManager::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
76
77 /*
78  * Path to internal storage where *only* root can access ASEC image files
79  */
80 const char *VolumeManager::SEC_ASECDIR_INT   = "/data/app-asec";
81
82 /*
83  * Path to where secure containers are mounted
84  */
85 const char *VolumeManager::ASECDIR           = "/mnt/asec";
86
87 /*
88  * Path to where OBBs are mounted
89  */
90 const char *VolumeManager::LOOPDIR           = "/mnt/obb";
91
92 bool VolumeManager::shutting_down = false;
93
94 static const char* kPathUserMount = "/mnt/user";
95 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
96
97 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
98
99 /* 512MiB is large enough for testing purposes */
100 static const unsigned int kSizeVirtualDisk = 536870912;
101
102 static const unsigned int kMajorBlockMmc = 179;
103 static const unsigned int kMajorBlockExperimentalMin = 240;
104 static const unsigned int kMajorBlockExperimentalMax = 254;
105
106 /* writes superblock at end of file or device given by name */
107 static int writeSuperBlock(const char* name, struct asec_superblock *sb, unsigned int numImgSectors) {
108     int sbfd = open(name, O_RDWR | O_CLOEXEC);
109     if (sbfd < 0) {
110         SLOGE("Failed to open %s for superblock write (%s)", name, strerror(errno));
111         return -1;
112     }
113
114     if (lseek(sbfd, (numImgSectors * 512), SEEK_SET) < 0) {
115         SLOGE("Failed to lseek for superblock (%s)", strerror(errno));
116         close(sbfd);
117         return -1;
118     }
119
120     if (write(sbfd, sb, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
121         SLOGE("Failed to write superblock (%s)", strerror(errno));
122         close(sbfd);
123         return -1;
124     }
125     close(sbfd);
126     return 0;
127 }
128
129 static unsigned long adjustSectorNumExt4(unsigned long numSectors) {
130     // Ext4 started to reserve 2% or 4096 clusters, whichever is smaller for
131     // preventing costly operations or unexpected ENOSPC error.
132     // Ext4::format() uses default block size without clustering.
133     unsigned long clusterSectors = 4096 / 512;
134     unsigned long reservedSectors = (numSectors * 2)/100 + (numSectors % 50 > 0);
135     numSectors += reservedSectors > (4096 * clusterSectors) ? (4096 * clusterSectors) : reservedSectors;
136     return ROUND_UP_POWER_OF_2(numSectors, 3);
137 }
138
139 static unsigned long adjustSectorNumFAT(unsigned long numSectors) {
140     /*
141     * Add some headroom
142     */
143     unsigned long fatSize = (((numSectors * 4) / 512) + 1) * 2;
144     numSectors += fatSize + 2;
145     /*
146     * FAT is aligned to 32 kb with 512b sectors.
147     */
148     return ROUND_UP_POWER_OF_2(numSectors, 6);
149 }
150
151 static int setupLoopDevice(char* buffer, size_t len, const char* asecFileName, const char* idHash, bool debug) {
152     if (Loop::lookupActive(idHash, buffer, len)) {
153         if (Loop::create(idHash, asecFileName, buffer, len)) {
154             SLOGE("ASEC loop device creation failed for %s (%s)", asecFileName, strerror(errno));
155             return -1;
156         }
157         if (debug) {
158             SLOGD("New loop device created at %s", buffer);
159         }
160     } else {
161         if (debug) {
162             SLOGD("Found active loopback for %s at %s", asecFileName, buffer);
163         }
164     }
165     return 0;
166 }
167
168 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) {
169     if (strcmp(key, "none")) {
170         if (Devmapper::lookupActive(idHash, buffer, len)) {
171             if (Devmapper::create(idHash, loopDevice, key, numImgSectors,
172                                   buffer, len)) {
173                 SLOGE("ASEC device mapping failed for %s (%s)", asecFileName, strerror(errno));
174                 return -1;
175             }
176             if (debug) {
177                 SLOGD("New devmapper instance created at %s", buffer);
178             }
179         } else {
180             if (debug) {
181                 SLOGD("Found active devmapper for %s at %s", asecFileName, buffer);
182             }
183         }
184         *createdDMDevice = true;
185     } else {
186         strlcpy(buffer, loopDevice, len);
187         *createdDMDevice = false;
188     }
189     return 0;
190 }
191
192 static void waitForDevMapper(const char *dmDevice) {
193     /*
194      * Wait for the device mapper node to be created. Sometimes it takes a
195      * while. Wait for up to 1 second. We could also inspect incoming uevents,
196      * but that would take more effort.
197      */
198     int tries = 25;
199     while (tries--) {
200         if (!access(dmDevice, F_OK) || errno != ENOENT) {
201             break;
202         }
203         usleep(40 * 1000);
204     }
205 }
206
207 VolumeManager *VolumeManager::sInstance = NULL;
208
209 VolumeManager *VolumeManager::Instance() {
210     if (!sInstance)
211         sInstance = new VolumeManager();
212     return sInstance;
213 }
214
215 VolumeManager::VolumeManager() {
216     mDebug = false;
217     mActiveContainers = new AsecIdCollection();
218     mBroadcaster = NULL;
219     mUmsSharingCount = 0;
220     mSavedDirtyRatio = -1;
221     // set dirty ratio to 0 when UMS is active
222     mUmsDirtyRatio = 0;
223 }
224
225 VolumeManager::~VolumeManager() {
226     delete mActiveContainers;
227 }
228
229 char *VolumeManager::asecHash(const char *id, char *buffer, size_t len) {
230     static const char* digits = "0123456789abcdef";
231
232     unsigned char sig[MD5_DIGEST_LENGTH];
233
234     if (buffer == NULL) {
235         SLOGE("Destination buffer is NULL");
236         errno = ESPIPE;
237         return NULL;
238     } else if (id == NULL) {
239         SLOGE("Source buffer is NULL");
240         errno = ESPIPE;
241         return NULL;
242     } else if (len < MD5_ASCII_LENGTH_PLUS_NULL) {
243         SLOGE("Target hash buffer size < %d bytes (%zu)",
244                 MD5_ASCII_LENGTH_PLUS_NULL, len);
245         errno = ESPIPE;
246         return NULL;
247     }
248
249     MD5(reinterpret_cast<const unsigned char*>(id), strlen(id), sig);
250
251     char *p = buffer;
252     for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
253         *p++ = digits[sig[i] >> 4];
254         *p++ = digits[sig[i] & 0x0F];
255     }
256     *p = '\0';
257
258     return buffer;
259 }
260
261 int VolumeManager::updateVirtualDisk() {
262     if (property_get_bool(kPropVirtualDisk, false)) {
263         if (access(kPathVirtualDisk, F_OK) != 0) {
264             Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
265         }
266
267         if (mVirtualDisk == nullptr) {
268             if (Loop::create(kPathVirtualDisk, mVirtualDiskPath) != 0) {
269                 LOG(ERROR) << "Failed to create virtual disk";
270                 return -1;
271             }
272
273             struct stat buf;
274             if (stat(mVirtualDiskPath.c_str(), &buf) < 0) {
275                 PLOG(ERROR) << "Failed to stat " << mVirtualDiskPath;
276                 return -1;
277             }
278
279             auto disk = new android::vold::Disk("virtual", buf.st_rdev, "virtual",
280                     android::vold::Disk::Flags::kAdoptable | android::vold::Disk::Flags::kSd);
281             disk->create();
282             mVirtualDisk = std::shared_ptr<android::vold::Disk>(disk);
283             mDisks.push_back(mVirtualDisk);
284         }
285     } else {
286         if (mVirtualDisk != nullptr) {
287             dev_t device = mVirtualDisk->getDevice();
288
289             auto i = mDisks.begin();
290             while (i != mDisks.end()) {
291                 if ((*i)->getDevice() == device) {
292                     (*i)->destroy();
293                     i = mDisks.erase(i);
294                 } else {
295                     ++i;
296                 }
297             }
298
299             Loop::destroyByDevice(mVirtualDiskPath.c_str());
300             mVirtualDisk = nullptr;
301         }
302
303         if (access(kPathVirtualDisk, F_OK) == 0) {
304             unlink(kPathVirtualDisk);
305         }
306     }
307     return 0;
308 }
309
310 int VolumeManager::setDebug(bool enable) {
311     mDebug = enable;
312     return 0;
313 }
314
315 int VolumeManager::start() {
316     // Always start from a clean slate by unmounting everything in
317     // directories that we own, in case we crashed.
318     unmountAll();
319
320     // Assume that we always have an emulated volume on internal
321     // storage; the framework will decide if it should be mounted.
322     CHECK(mInternalEmulated == nullptr);
323     mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(
324             new android::vold::EmulatedVolume("/data/media"));
325     mInternalEmulated->create();
326
327     // Consider creating a virtual disk
328     updateVirtualDisk();
329
330     return 0;
331 }
332
333 int VolumeManager::stop() {
334     CHECK(mInternalEmulated != nullptr);
335     mInternalEmulated->destroy();
336     mInternalEmulated = nullptr;
337     return 0;
338 }
339
340 void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
341     std::lock_guard<std::mutex> lock(mLock);
342
343     if (mDebug) {
344         LOG(VERBOSE) << "----------------";
345         LOG(VERBOSE) << "handleBlockEvent with action " << (int) evt->getAction();
346         evt->dump();
347     }
348
349     std::string eventPath(evt->findParam("DEVPATH")?evt->findParam("DEVPATH"):"");
350     std::string devType(evt->findParam("DEVTYPE")?evt->findParam("DEVTYPE"):"");
351
352     if (devType != "disk") return;
353
354     int major = atoi(evt->findParam("MAJOR"));
355     int minor = atoi(evt->findParam("MINOR"));
356     dev_t device = makedev(major, minor);
357
358     switch (evt->getAction()) {
359     case NetlinkEvent::Action::kAdd: {
360         for (const auto& source : mDiskSources) {
361             if (source->matches(eventPath)) {
362                 // For now, assume that MMC and virtio-blk (the latter is
363                 // emulator-specific; see Disk.cpp for details) devices are SD,
364                 // and that everything else is USB
365                 int flags = source->getFlags();
366                 if (major == kMajorBlockMmc
367                     || (android::vold::IsRunningInEmulator()
368                     && major >= (int) kMajorBlockExperimentalMin
369                     && major <= (int) kMajorBlockExperimentalMax)) {
370                     flags |= android::vold::Disk::Flags::kSd;
371                 } else {
372                     flags |= android::vold::Disk::Flags::kUsb;
373                 }
374
375                 auto disk = new android::vold::Disk(eventPath, device,
376                         source->getNickname(), flags);
377                 disk->create();
378                 mDisks.push_back(std::shared_ptr<android::vold::Disk>(disk));
379                 break;
380             }
381         }
382         break;
383     }
384     case NetlinkEvent::Action::kChange: {
385         LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
386         for (const auto& disk : mDisks) {
387             if (disk->getDevice() == device) {
388                 disk->readMetadata();
389                 disk->readPartitions();
390             }
391         }
392         break;
393     }
394     case NetlinkEvent::Action::kRemove: {
395         auto i = mDisks.begin();
396         while (i != mDisks.end()) {
397             if ((*i)->getDevice() == device) {
398                 (*i)->destroy();
399                 i = mDisks.erase(i);
400             } else {
401                 ++i;
402             }
403         }
404         break;
405     }
406     default: {
407         LOG(WARNING) << "Unexpected block event action " << (int) evt->getAction();
408         break;
409     }
410     }
411 }
412
413 void VolumeManager::addDiskSource(const std::shared_ptr<DiskSource>& diskSource) {
414     std::lock_guard<std::mutex> lock(mLock);
415     mDiskSources.push_back(diskSource);
416 }
417
418 std::shared_ptr<android::vold::Disk> VolumeManager::findDisk(const std::string& id) {
419     for (auto disk : mDisks) {
420         if (disk->getId() == id) {
421             return disk;
422         }
423     }
424     return nullptr;
425 }
426
427 std::shared_ptr<android::vold::VolumeBase> VolumeManager::findVolume(const std::string& id) {
428     if (mInternalEmulated->getId() == id) {
429         return mInternalEmulated;
430     }
431     for (const auto& disk : mDisks) {
432         auto vol = disk->findVolume(id);
433         if (vol != nullptr) {
434             return vol;
435         }
436     }
437     return nullptr;
438 }
439
440 void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
441         std::list<std::string>& list) {
442     list.clear();
443     for (const auto& disk : mDisks) {
444         disk->listVolumes(type, list);
445     }
446 }
447
448 nsecs_t VolumeManager::benchmarkPrivate(const std::string& id) {
449     std::string path;
450     if (id == "private" || id == "null") {
451         path = "/data";
452     } else {
453         auto vol = findVolume(id);
454         if (vol != nullptr && vol->getState() == android::vold::VolumeBase::State::kMounted) {
455             path = vol->getPath();
456         }
457     }
458
459     if (path.empty()) {
460         LOG(WARNING) << "Failed to find volume for " << id;
461         return -1;
462     }
463
464     return android::vold::BenchmarkPrivate(path);
465 }
466
467 int VolumeManager::forgetPartition(const std::string& partGuid) {
468     std::string normalizedGuid;
469     if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
470         LOG(WARNING) << "Invalid GUID " << partGuid;
471         return -1;
472     }
473
474     std::string keyPath = android::vold::BuildKeyPath(normalizedGuid);
475     if (unlink(keyPath.c_str()) != 0) {
476         LOG(ERROR) << "Failed to unlink " << keyPath;
477         return -1;
478     }
479
480     return 0;
481 }
482
483 int VolumeManager::linkPrimary(userid_t userId) {
484     std::string source(mPrimary->getPath());
485     if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
486         source = StringPrintf("%s/%d", source.c_str(), userId);
487         fs_prepare_dir(source.c_str(), 0755, AID_ROOT, AID_ROOT);
488     }
489
490     std::string target(StringPrintf("/mnt/user/%d/primary", userId));
491     if (TEMP_FAILURE_RETRY(unlink(target.c_str()))) {
492         if (errno != ENOENT) {
493             SLOGW("Failed to unlink %s: %s", target.c_str(), strerror(errno));
494         }
495     }
496     LOG(DEBUG) << "Linking " << source << " to " << target;
497     if (TEMP_FAILURE_RETRY(symlink(source.c_str(), target.c_str()))) {
498         SLOGW("Failed to link %s to %s: %s", source.c_str(), target.c_str(),
499                 strerror(errno));
500         return -errno;
501     }
502     return 0;
503 }
504
505 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
506     mAddedUsers[userId] = userSerialNumber;
507     return 0;
508 }
509
510 int VolumeManager::onUserRemoved(userid_t userId) {
511     mAddedUsers.erase(userId);
512     return 0;
513 }
514
515 int VolumeManager::onUserStarted(userid_t userId) {
516     // Note that sometimes the system will spin up processes from Zygote
517     // before actually starting the user, so we're okay if Zygote
518     // already created this directory.
519     std::string path(StringPrintf("%s/%d", kPathUserMount, userId));
520     fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
521
522     mStartedUsers.insert(userId);
523     if (mPrimary) {
524         linkPrimary(userId);
525     }
526     return 0;
527 }
528
529 int VolumeManager::onUserStopped(userid_t userId) {
530     mStartedUsers.erase(userId);
531     return 0;
532 }
533
534 int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
535     mPrimary = vol;
536     for (userid_t userId : mStartedUsers) {
537         linkPrimary(userId);
538     }
539     return 0;
540 }
541
542 static int unmount_tree(const char* path) {
543     size_t path_len = strlen(path);
544
545     FILE* fp = setmntent("/proc/mounts", "r");
546     if (fp == NULL) {
547         ALOGE("Error opening /proc/mounts: %s", strerror(errno));
548         return -errno;
549     }
550
551     // Some volumes can be stacked on each other, so force unmount in
552     // reverse order to give us the best chance of success.
553     std::list<std::string> toUnmount;
554     mntent* mentry;
555     while ((mentry = getmntent(fp)) != NULL) {
556         if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
557             toUnmount.push_front(std::string(mentry->mnt_dir));
558         }
559     }
560     endmntent(fp);
561
562     for (const auto& path : toUnmount) {
563         if (umount2(path.c_str(), MNT_DETACH)) {
564             ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
565         }
566     }
567     return 0;
568 }
569
570 int VolumeManager::remountUid(uid_t uid, const std::string& mode) {
571     LOG(DEBUG) << "Remounting " << uid << " as mode " << mode;
572
573     DIR* dir;
574     struct dirent* de;
575     char rootName[PATH_MAX];
576     char pidName[PATH_MAX];
577     int pidFd;
578     int nsFd;
579     struct stat sb;
580     pid_t child;
581
582     if (!(dir = opendir("/proc"))) {
583         PLOG(ERROR) << "Failed to opendir";
584         return -1;
585     }
586
587     // Figure out root namespace to compare against below
588     if (android::vold::SaneReadLinkAt(dirfd(dir), "1/ns/mnt", rootName, PATH_MAX) == -1) {
589         PLOG(ERROR) << "Failed to readlink";
590         closedir(dir);
591         return -1;
592     }
593
594     // Poke through all running PIDs look for apps running as UID
595     while ((de = readdir(dir))) {
596         pidFd = -1;
597         nsFd = -1;
598
599         pidFd = openat(dirfd(dir), de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
600         if (pidFd < 0) {
601             goto next;
602         }
603         if (fstat(pidFd, &sb) != 0) {
604             PLOG(WARNING) << "Failed to stat " << de->d_name;
605             goto next;
606         }
607         if (sb.st_uid != uid) {
608             goto next;
609         }
610
611         // Matches so far, but refuse to touch if in root namespace
612         LOG(DEBUG) << "Found matching PID " << de->d_name;
613         if (android::vold::SaneReadLinkAt(pidFd, "ns/mnt", pidName, PATH_MAX) == -1) {
614             PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
615             goto next;
616         }
617         if (!strcmp(rootName, pidName)) {
618             LOG(WARNING) << "Skipping due to root namespace";
619             goto next;
620         }
621
622         // We purposefully leave the namespace open across the fork
623         nsFd = openat(pidFd, "ns/mnt", O_RDONLY); // not O_CLOEXEC
624         if (nsFd < 0) {
625             PLOG(WARNING) << "Failed to open namespace for " << de->d_name;
626             goto next;
627         }
628
629         if (!(child = fork())) {
630             if (setns(nsFd, CLONE_NEWNS) != 0) {
631                 PLOG(ERROR) << "Failed to setns for " << de->d_name;
632                 _exit(1);
633             }
634
635             unmount_tree("/storage");
636
637             std::string storageSource;
638             if (mode == "default") {
639                 storageSource = "/mnt/runtime/default";
640             } else if (mode == "read") {
641                 storageSource = "/mnt/runtime/read";
642             } else if (mode == "write") {
643                 storageSource = "/mnt/runtime/write";
644             } else {
645                 // Sane default of no storage visible
646                 _exit(0);
647             }
648             if (TEMP_FAILURE_RETRY(mount(storageSource.c_str(), "/storage",
649                     NULL, MS_BIND | MS_REC, NULL)) == -1) {
650                 PLOG(ERROR) << "Failed to mount " << storageSource << " for "
651                         << de->d_name;
652                 _exit(1);
653             }
654             if (TEMP_FAILURE_RETRY(mount(NULL, "/storage", NULL,
655                     MS_REC | MS_SLAVE, NULL)) == -1) {
656                 PLOG(ERROR) << "Failed to set MS_SLAVE to /storage for "
657                         << de->d_name;
658                 _exit(1);
659             }
660
661             // Mount user-specific symlink helper into place
662             userid_t user_id = multiuser_get_user_id(uid);
663             std::string userSource(StringPrintf("/mnt/user/%d", user_id));
664             if (TEMP_FAILURE_RETRY(mount(userSource.c_str(), "/storage/self",
665                     NULL, MS_BIND, NULL)) == -1) {
666                 PLOG(ERROR) << "Failed to mount " << userSource << " for "
667                         << de->d_name;
668                 _exit(1);
669             }
670
671             _exit(0);
672         }
673
674         if (child == -1) {
675             PLOG(ERROR) << "Failed to fork";
676             goto next;
677         } else {
678             TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
679         }
680
681 next:
682         close(nsFd);
683         close(pidFd);
684     }
685     closedir(dir);
686     return 0;
687 }
688
689 int VolumeManager::reset() {
690     // Tear down all existing disks/volumes and start from a blank slate so
691     // newly connected framework hears all events.
692     mInternalEmulated->destroy();
693     mInternalEmulated->create();
694     for (const auto& disk : mDisks) {
695         disk->destroy();
696         disk->create();
697     }
698     updateVirtualDisk();
699     mAddedUsers.clear();
700     mStartedUsers.clear();
701     return 0;
702 }
703
704 // Can be called twice (sequentially) during shutdown. should be safe for that.
705 int VolumeManager::shutdown() {
706     if (mInternalEmulated == nullptr) {
707         return 0; // already shutdown
708     }
709     shutting_down = true;
710     mInternalEmulated->destroy();
711     mInternalEmulated = nullptr;
712     for (const auto& disk : mDisks) {
713         disk->destroy();
714     }
715     mDisks.clear();
716     shutting_down = false;
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         strlcpy(dmDevice, loopDevice, sizeof(dmDevice));
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     strlcpy(loopDir, VolumeManager::LOOPDIR, sizeof(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 }