1 /*
2  * Copyright (C) 2018 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 <linux/fs.h>
21 #include <selinux/selinux.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/mount.h>
26 #include <sys/param.h>
27 #include <sys/stat.h>
28 #include <sys/statvfs.h>
29 #include <sys/types.h>
30 #include <sys/utsname.h>
31 #include <sys/vfs.h>
32 #include <unistd.h>
33 
34 #include <algorithm>
35 #include <memory>
36 #include <optional>
37 #include <string>
38 #include <vector>
39 
40 #include <android-base/file.h>
41 #include <android-base/macros.h>
42 #include <android-base/properties.h>
43 #include <android-base/strings.h>
44 #include <android-base/unique_fd.h>
45 #include <ext4_utils/ext4_utils.h>
46 #include <fs_mgr.h>
47 #include <fs_mgr/file_wait.h>
48 #include <fs_mgr_dm_linear.h>
49 #include <fs_mgr_overlayfs.h>
50 #include <fstab/fstab.h>
51 #include <libdm/dm.h>
52 #include <libfiemap/image_manager.h>
53 #include <libgsi/libgsi.h>
54 #include <liblp/builder.h>
55 #include <liblp/liblp.h>
56 #include <storage_literals/storage_literals.h>
57 
58 #include "fs_mgr_priv.h"
59 #include "fs_mgr_priv_overlayfs.h"
60 #include "libfiemap/utility.h"
61 
62 using namespace std::literals;
63 using namespace android::dm;
64 using namespace android::fs_mgr;
65 using namespace android::storage_literals;
66 using android::fiemap::FilesystemHasReliablePinning;
67 using android::fiemap::IImageManager;
68 
69 namespace {
70 
71 constexpr char kDataScratchSizeMbProp[] = "fs_mgr.overlayfs.data_scratch_size_mb";
72 constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage";
73 
fs_mgr_access(const std::string & path)74 bool fs_mgr_access(const std::string& path) {
75     return access(path.c_str(), F_OK) == 0;
76 }
77 
78 const auto kLowerdirOption = "lowerdir="s;
79 const auto kUpperdirOption = "upperdir="s;
80 
fs_mgr_in_recovery()81 bool fs_mgr_in_recovery() {
82     // Check the existence of recovery binary instead of using the compile time
83     // __ANDROID_RECOVERY__ macro.
84     // If BOARD_USES_RECOVERY_AS_BOOT is true, both normal and recovery boot
85     // mode would use the same init binary, which would mean during normal boot
86     // the '/init' binary is actually a symlink pointing to
87     // init_second_stage.recovery, which would be compiled with
88     // __ANDROID_RECOVERY__ defined.
89     return fs_mgr_access("/system/bin/recovery");
90 }
91 
fs_mgr_is_dsu_running()92 bool fs_mgr_is_dsu_running() {
93     // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
94     // never called in recovery, the return value of android::gsi::IsGsiRunning()
95     // is not well-defined. In this case, just return false as being in recovery
96     // implies not running a DSU system.
97     if (fs_mgr_in_recovery()) return false;
98     return android::gsi::IsGsiRunning();
99 }
100 
101 // list of acceptable overlayfs backing storage
102 const auto kScratchMountPoint = "/mnt/scratch"s;
103 const auto kCacheMountPoint = "/cache"s;
104 
IsABDevice()105 bool IsABDevice() {
106     return !android::base::GetProperty("ro.boot.slot_suffix", "").empty();
107 }
108 
OverlayMountPoints()109 std::vector<const std::string> OverlayMountPoints() {
110     // Never fallback to legacy cache mount point if within a DSU system,
111     // because running a DSU system implies the device supports dynamic
112     // partitions, which means legacy cache mustn't be used.
113     if (fs_mgr_is_dsu_running()) {
114         return {kScratchMountPoint};
115     }
116 
117     // For non-A/B devices prefer cache backing storage if
118     // kPreferCacheBackingStorageProp property set.
119     if (!IsABDevice() && android::base::GetBoolProperty(kPreferCacheBackingStorageProp, false) &&
120         android::base::GetIntProperty("ro.vendor.api_level", -1) < __ANDROID_API_T__) {
121         return {kCacheMountPoint, kScratchMountPoint};
122     }
123 
124     return {kScratchMountPoint, kCacheMountPoint};
125 }
126 
127 // Return true if everything is mounted, but before adb is started.  Right
128 // after 'trigger load_persist_props_action' is done.
fs_mgr_boot_completed()129 bool fs_mgr_boot_completed() {
130     return android::base::GetBoolProperty("ro.persistent_properties.ready", false);
131 }
132 
fs_mgr_is_dir(const std::string & path)133 bool fs_mgr_is_dir(const std::string& path) {
134     struct stat st;
135     return !stat(path.c_str(), &st) && S_ISDIR(st.st_mode);
136 }
137 
fs_mgr_rw_access(const std::string & path)138 bool fs_mgr_rw_access(const std::string& path) {
139     if (path.empty()) return false;
140     return access(path.c_str(), R_OK | W_OK) == 0;
141 }
142 
143 // At less than 1% or 8MB of free space return value of false,
144 // means we will try to wrap with overlayfs.
fs_mgr_filesystem_has_space(const std::string & mount_point)145 bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
146     // If we have access issues to find out space remaining, return true
147     // to prevent us trying to override with overlayfs.
148     struct statvfs vst;
149     if (statvfs(mount_point.c_str(), &vst)) {
150         PLOG(ERROR) << "statvfs " << mount_point;
151         return true;
152     }
153 
154     static constexpr int kPercentThreshold = 1;                       // 1%
155     static constexpr unsigned long kSizeThreshold = 8 * 1024 * 1024;  // 8MB
156 
157     return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100)) &&
158            (static_cast<uint64_t>(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold;
159 }
160 
161 const auto kPhysicalDevice = "/dev/block/by-name/"s;
162 constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata";
163 
164 // Note: this is meant only for recovery/first-stage init.
ScratchIsOnData()165 bool ScratchIsOnData() {
166     // The scratch partition of DSU is managed by gsid.
167     if (fs_mgr_is_dsu_running()) {
168         return false;
169     }
170     return fs_mgr_access(kScratchImageMetadata);
171 }
172 
fs_mgr_update_blk_device(FstabEntry * entry)173 bool fs_mgr_update_blk_device(FstabEntry* entry) {
174     if (entry->fs_mgr_flags.logical) {
175         fs_mgr_update_logical_partition(entry);
176     }
177     if (fs_mgr_access(entry->blk_device)) {
178         return true;
179     }
180     if (entry->blk_device != "/dev/root") {
181         return false;
182     }
183 
184     // special case for system-as-root (taimen and others)
185     auto blk_device = kPhysicalDevice + "system";
186     if (!fs_mgr_access(blk_device)) {
187         blk_device += fs_mgr_get_slot_suffix();
188         if (!fs_mgr_access(blk_device)) {
189             return false;
190         }
191     }
192     entry->blk_device = blk_device;
193     return true;
194 }
195 
fs_mgr_has_shared_blocks(const std::string & mount_point,const std::string & dev)196 bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) {
197     struct statfs fs;
198     if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) ||
199         (fs.f_type != EXT4_SUPER_MAGIC)) {
200         return false;
201     }
202 
203     android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
204     if (fd < 0) return false;
205 
206     struct ext4_super_block sb;
207     if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) ||
208         (TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) {
209         return false;
210     }
211 
212     struct fs_info info;
213     if (ext4_parse_sb(&sb, &info) < 0) return false;
214 
215     return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0;
216 }
217 
218 #define F2FS_SUPER_OFFSET 1024
219 #define F2FS_FEATURE_OFFSET 2180
220 #define F2FS_FEATURE_RO 0x4000
fs_mgr_is_read_only_f2fs(const std::string & dev)221 bool fs_mgr_is_read_only_f2fs(const std::string& dev) {
222     if (!fs_mgr_is_f2fs(dev)) return false;
223 
224     android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
225     if (fd < 0) return false;
226 
227     __le32 feat;
228     if ((TEMP_FAILURE_RETRY(lseek64(fd, F2FS_SUPER_OFFSET + F2FS_FEATURE_OFFSET, SEEK_SET)) < 0) ||
229         (TEMP_FAILURE_RETRY(read(fd, &feat, sizeof(feat))) < 0)) {
230         return false;
231     }
232 
233     return (feat & cpu_to_le32(F2FS_FEATURE_RO)) != 0;
234 }
235 
fs_mgr_overlayfs_enabled(FstabEntry * entry)236 bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
237     // readonly filesystem, can not be mount -o remount,rw
238     // for squashfs, erofs or if free space is (near) zero making such a remount
239     // virtually useless, or if there are shared blocks that prevent remount,rw
240     if (!fs_mgr_filesystem_has_space(entry->mount_point)) {
241         return true;
242     }
243 
244     // blk_device needs to be setup so we can check superblock.
245     // If we fail here, because during init first stage and have doubts.
246     if (!fs_mgr_update_blk_device(entry)) {
247         return true;
248     }
249 
250     // f2fs read-only mode doesn't support remount,rw
251     if (fs_mgr_is_read_only_f2fs(entry->blk_device)) {
252         return true;
253     }
254 
255     // check if ext4 de-dupe
256     auto has_shared_blocks = fs_mgr_has_shared_blocks(entry->mount_point, entry->blk_device);
257     if (!has_shared_blocks && (entry->mount_point == "/system")) {
258         has_shared_blocks = fs_mgr_has_shared_blocks("/", entry->blk_device);
259     }
260     return has_shared_blocks;
261 }
262 
fs_mgr_rm_all(const std::string & path,bool * change=nullptr,int level=0)263 bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
264     std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
265     if (!dir) {
266         if (errno == ENOENT) {
267             return true;
268         }
269         PERROR << "opendir " << path << " depth=" << level;
270         if ((errno == EPERM) && (level != 0)) {
271             return true;
272         }
273         return false;
274     }
275     dirent* entry;
276     auto ret = true;
277     while ((entry = readdir(dir.get()))) {
278         if (("."s == entry->d_name) || (".."s == entry->d_name)) continue;
279         auto file = path + "/" + entry->d_name;
280         if (entry->d_type == DT_UNKNOWN) {
281             struct stat st;
282             if (!lstat(file.c_str(), &st) && (st.st_mode & S_IFDIR)) entry->d_type = DT_DIR;
283         }
284         if (entry->d_type == DT_DIR) {
285             ret &= fs_mgr_rm_all(file, change, level + 1);
286             if (!rmdir(file.c_str())) {
287                 if (change) *change = true;
288             } else {
289                 if (errno != ENOENT) ret = false;
290                 PERROR << "rmdir " << file << " depth=" << level;
291             }
292             continue;
293         }
294         if (!unlink(file.c_str())) {
295             if (change) *change = true;
296         } else {
297             if (errno != ENOENT) ret = false;
298             PERROR << "rm " << file << " depth=" << level;
299         }
300     }
301     return ret;
302 }
303 
304 const auto kUpperName = "upper"s;
305 const auto kWorkName = "work"s;
306 const auto kOverlayTopDir = "/overlay"s;
307 
fs_mgr_get_overlayfs_candidate(const std::string & mount_point)308 std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) {
309     if (!fs_mgr_is_dir(mount_point)) return "";
310     const auto base = android::base::Basename(mount_point) + "/";
311     for (const auto& overlay_mount_point : OverlayMountPoints()) {
312         auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
313         auto upper = dir + kUpperName;
314         if (!fs_mgr_is_dir(upper)) continue;
315         auto work = dir + kWorkName;
316         if (!fs_mgr_is_dir(work)) continue;
317         if (!fs_mgr_rw_access(work)) continue;
318         return dir;
319     }
320     return "";
321 }
322 
KernelSupportsUserXattrs()323 static inline bool KernelSupportsUserXattrs() {
324     struct utsname uts;
325     uname(&uts);
326 
327     int major, minor;
328     if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
329         return false;
330     }
331     return major > 5 || (major == 5 && minor >= 15);
332 }
333 
fs_mgr_mount_point(const std::string & mount_point)334 const std::string fs_mgr_mount_point(const std::string& mount_point) {
335     if ("/"s != mount_point) return mount_point;
336     return "/system";
337 }
338 
339 // default options for mount_point, returns empty string for none available.
fs_mgr_get_overlayfs_options(const FstabEntry & entry)340 std::string fs_mgr_get_overlayfs_options(const FstabEntry& entry) {
341     const auto mount_point = fs_mgr_mount_point(entry.mount_point);
342     auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
343     if (candidate.empty()) return "";
344     auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName +
345                ",workdir=" + candidate + kWorkName;
346     if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
347         ret += ",override_creds=off";
348     }
349     if (KernelSupportsUserXattrs()) {
350         ret += ",userxattr";
351     }
352     for (const auto& flag : android::base::Split(entry.fs_options, ",")) {
353         if (android::base::StartsWith(flag, "context=")) {
354             ret += "," + flag;
355         }
356     }
357     return ret;
358 }
359 
360 constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
361 
362 class AutoSetFsCreateCon final {
363   public:
AutoSetFsCreateCon()364     AutoSetFsCreateCon() {}
AutoSetFsCreateCon(const std::string & context)365     AutoSetFsCreateCon(const std::string& context) { Set(context); }
~AutoSetFsCreateCon()366     ~AutoSetFsCreateCon() { Restore(); }
367 
Ok() const368     bool Ok() const { return ok_; }
Set(const std::string & context)369     bool Set(const std::string& context) {
370         if (setfscreatecon(context.c_str())) {
371             PLOG(ERROR) << "setfscreatecon " << context;
372             return false;
373         }
374         ok_ = true;
375         return true;
376     }
Restore()377     bool Restore() {
378         if (restored_ || !ok_) {
379             return true;
380         }
381         if (setfscreatecon(nullptr)) {
382             PLOG(ERROR) << "setfscreatecon null";
383             return false;
384         }
385         restored_ = true;
386         return true;
387     }
388 
389   private:
390     bool ok_ = false;
391     bool restored_ = false;
392 };
393 
fs_mgr_overlayfs_setup_dir(const std::string & dir)394 std::string fs_mgr_overlayfs_setup_dir(const std::string& dir) {
395     auto top = dir + kOverlayTopDir;
396 
397     AutoSetFsCreateCon createcon(kOverlayfsFileContext);
398     if (!createcon.Ok()) {
399         return {};
400     }
401     if (mkdir(top.c_str(), 0755) != 0 && errno != EEXIST) {
402         PERROR << "mkdir " << top;
403         return {};
404     }
405     if (!createcon.Restore()) {
406         return {};
407     }
408     return top;
409 }
410 
fs_mgr_overlayfs_setup_one(const std::string & overlay,const std::string & mount_point,bool * want_reboot)411 bool fs_mgr_overlayfs_setup_one(const std::string& overlay, const std::string& mount_point,
412                                 bool* want_reboot) {
413     if (fs_mgr_overlayfs_already_mounted(mount_point)) {
414         return true;
415     }
416     auto fsrec_mount_point = overlay + "/" + android::base::Basename(mount_point) + "/";
417 
418     AutoSetFsCreateCon createcon(kOverlayfsFileContext);
419     if (!createcon.Ok()) {
420         return false;
421     }
422     if (mkdir(fsrec_mount_point.c_str(), 0755) != 0 && errno != EEXIST) {
423         PERROR << "mkdir " << fsrec_mount_point;
424         return false;
425     }
426     if (mkdir((fsrec_mount_point + kWorkName).c_str(), 0755) != 0 && errno != EEXIST) {
427         PERROR << "mkdir " << fsrec_mount_point << kWorkName;
428         return false;
429     }
430     if (!createcon.Restore()) {
431         return false;
432     }
433 
434     createcon = {};
435 
436     auto new_context = fs_mgr_get_context(mount_point);
437     if (new_context.empty() || !createcon.Set(new_context)) {
438         return false;
439     }
440 
441     auto upper = fsrec_mount_point + kUpperName;
442     if (mkdir(upper.c_str(), 0755) != 0 && errno != EEXIST) {
443         PERROR << "mkdir " << upper;
444         return false;
445     }
446     if (!createcon.Restore()) {
447         return false;
448     }
449 
450     if (want_reboot) *want_reboot = true;
451 
452     return true;
453 }
454 
fs_mgr_overlayfs_slot_number()455 uint32_t fs_mgr_overlayfs_slot_number() {
456     return SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
457 }
458 
fs_mgr_overlayfs_super_device(uint32_t slot_number)459 std::string fs_mgr_overlayfs_super_device(uint32_t slot_number) {
460     return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number);
461 }
462 
fs_mgr_overlayfs_has_logical(const Fstab & fstab)463 bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) {
464     for (const auto& entry : fstab) {
465         if (entry.fs_mgr_flags.logical) {
466             return true;
467         }
468     }
469     return false;
470 }
471 
472 // Returns true if immediate unmount succeeded and the scratch mount point was
473 // removed.
fs_mgr_overlayfs_umount_scratch()474 bool fs_mgr_overlayfs_umount_scratch() {
475     if (umount(kScratchMountPoint.c_str()) != 0) {
476         return false;
477     }
478     if (rmdir(kScratchMountPoint.c_str()) != 0 && errno != ENOENT) {
479         PLOG(ERROR) << "rmdir " << kScratchMountPoint;
480     }
481     return true;
482 }
483 
TeardownDataScratch(IImageManager * images,const std::string & partition_name,bool was_mounted)484 OverlayfsTeardownResult TeardownDataScratch(IImageManager* images,
485                                             const std::string& partition_name, bool was_mounted) {
486     if (!images) {
487         return OverlayfsTeardownResult::Error;
488     }
489     if (!images->DisableImage(partition_name)) {
490         return OverlayfsTeardownResult::Error;
491     }
492     if (was_mounted) {
493         // If overlayfs was mounted, don't bother trying to unmap since
494         // it'll fail and create error spam.
495         return OverlayfsTeardownResult::Busy;
496     }
497     if (!images->UnmapImageIfExists(partition_name)) {
498         return OverlayfsTeardownResult::Busy;
499     }
500     if (!images->DeleteBackingImage(partition_name)) {
501         return OverlayfsTeardownResult::Busy;
502     }
503     return OverlayfsTeardownResult::Ok;
504 }
505 
fs_mgr_overlayfs_teardown_scratch(const std::string & overlay,bool * change)506 OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& overlay,
507                                                           bool* change) {
508     // umount and delete kScratchMountPoint storage if we have logical partitions
509     if (overlay != kScratchMountPoint) {
510         return OverlayfsTeardownResult::Ok;
511     }
512 
513     // Validation check.
514     if (fs_mgr_is_dsu_running()) {
515         LERROR << "Destroying DSU scratch is not allowed.";
516         return OverlayfsTeardownResult::Error;
517     }
518 
519     bool was_mounted = fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false);
520     if (was_mounted) {
521         fs_mgr_overlayfs_umount_scratch();
522     }
523 
524     const auto partition_name = android::base::Basename(kScratchMountPoint);
525 
526     auto images = IImageManager::Open("remount", 10s);
527     if (images && images->BackingImageExists(partition_name)) {
528         // No need to check super partition, if we knew we had a scratch device
529         // in /data.
530         return TeardownDataScratch(images.get(), partition_name, was_mounted);
531     }
532 
533     auto slot_number = fs_mgr_overlayfs_slot_number();
534     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
535     if (!fs_mgr_rw_access(super_device)) {
536         return OverlayfsTeardownResult::Ok;
537     }
538 
539     auto builder = MetadataBuilder::New(super_device, slot_number);
540     if (!builder) {
541         return OverlayfsTeardownResult::Ok;
542     }
543     if (builder->FindPartition(partition_name) == nullptr) {
544         return OverlayfsTeardownResult::Ok;
545     }
546     builder->RemovePartition(partition_name);
547     auto metadata = builder->Export();
548     if (metadata && UpdatePartitionTable(super_device, *metadata.get(), slot_number)) {
549         if (change) *change = true;
550         if (!DestroyLogicalPartition(partition_name)) {
551             return OverlayfsTeardownResult::Error;
552         }
553     } else {
554         LERROR << "delete partition " << overlay;
555         return OverlayfsTeardownResult::Error;
556     }
557 
558     if (was_mounted) {
559         return OverlayfsTeardownResult::Busy;
560     }
561     return OverlayfsTeardownResult::Ok;
562 }
563 
fs_mgr_overlayfs_teardown_one(const std::string & overlay,const std::string & mount_point,bool * change,bool * should_destroy_scratch=nullptr)564 bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
565                                    bool* change, bool* should_destroy_scratch = nullptr) {
566     const auto top = overlay + kOverlayTopDir;
567 
568     if (!fs_mgr_access(top)) {
569         if (should_destroy_scratch) *should_destroy_scratch = true;
570         return true;
571     }
572 
573     auto cleanup_all = mount_point.empty();
574     const auto partition_name = android::base::Basename(mount_point);
575     const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
576     const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir.substr(1) + ".teardown"
577                                      : top + "/." + partition_name + ".teardown";
578     auto ret = fs_mgr_rm_all(newpath);
579     if (!rename(oldpath.c_str(), newpath.c_str())) {
580         if (change) *change = true;
581     } else if (errno != ENOENT) {
582         ret = false;
583         PERROR << "mv " << oldpath << " " << newpath;
584     }
585     ret &= fs_mgr_rm_all(newpath, change);
586     if (!rmdir(newpath.c_str())) {
587         if (change) *change = true;
588     } else if (errno != ENOENT) {
589         ret = false;
590         PERROR << "rmdir " << newpath;
591     }
592     if (!cleanup_all) {
593         if (!rmdir(top.c_str())) {
594             if (change) *change = true;
595             cleanup_all = true;
596         } else if (errno == ENOTEMPTY) {
597             cleanup_all = true;
598             // cleanup all if the content is all hidden (leading .)
599             std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(top.c_str()), closedir);
600             if (!dir) {
601                 PERROR << "opendir " << top;
602             } else {
603                 dirent* entry;
604                 while ((entry = readdir(dir.get()))) {
605                     if (entry->d_name[0] != '.') {
606                         cleanup_all = false;
607                         break;
608                     }
609                 }
610             }
611         } else if (errno == ENOENT) {
612             cleanup_all = true;
613         } else {
614             ret = false;
615             PERROR << "rmdir " << top;
616         }
617     }
618     if (should_destroy_scratch) *should_destroy_scratch = cleanup_all;
619     return ret;
620 }
621 
fs_mgr_overlayfs_set_shared_mount(const std::string & mount_point,bool shared_flag)622 bool fs_mgr_overlayfs_set_shared_mount(const std::string& mount_point, bool shared_flag) {
623     auto ret = mount(nullptr, mount_point.c_str(), nullptr, shared_flag ? MS_SHARED : MS_PRIVATE,
624                      nullptr);
625     if (ret) {
626         PERROR << "__mount(target=" << mount_point
627                << ",flag=" << (shared_flag ? "MS_SHARED" : "MS_PRIVATE") << ")=" << ret;
628         // If "/system" doesn't look like a mountpoint, retry with "/".
629         if (errno == EINVAL && mount_point == "/system") {
630             return fs_mgr_overlayfs_set_shared_mount("/", shared_flag);
631         }
632         return false;
633     }
634     return true;
635 }
636 
fs_mgr_overlayfs_move_mount(const std::string & source,const std::string & target)637 bool fs_mgr_overlayfs_move_mount(const std::string& source, const std::string& target) {
638     auto ret = mount(source.c_str(), target.c_str(), nullptr, MS_MOVE, nullptr);
639     if (ret) {
640         PERROR << "__mount(source=" << source << ",target=" << target << ",flag=MS_MOVE)=" << ret;
641         return false;
642     }
643     return true;
644 }
645 
646 struct mount_info {
647     std::string mount_point;
648     bool shared_flag;
649 };
650 
ReadMountinfoFromFile(const std::string & path)651 std::vector<mount_info> ReadMountinfoFromFile(const std::string& path) {
652     std::vector<mount_info> info;
653 
654     auto file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
655     if (!file) {
656         PERROR << __FUNCTION__ << "(): cannot open file: '" << path << "'";
657         return info;
658     }
659 
660     ssize_t len;
661     size_t alloc_len = 0;
662     char* line = nullptr;
663     while ((len = getline(&line, &alloc_len, file.get())) != -1) {
664         /* if the last character is a newline, shorten the string by 1 byte */
665         if (line[len - 1] == '\n') {
666             line[len - 1] = '\0';
667         }
668 
669         static constexpr char delim[] = " \t";
670         char* save_ptr;
671         if (!strtok_r(line, delim, &save_ptr)) {
672             LERROR << "Error parsing mount ID";
673             break;
674         }
675         if (!strtok_r(nullptr, delim, &save_ptr)) {
676             LERROR << "Error parsing parent ID";
677             break;
678         }
679         if (!strtok_r(nullptr, delim, &save_ptr)) {
680             LERROR << "Error parsing mount source";
681             break;
682         }
683         if (!strtok_r(nullptr, delim, &save_ptr)) {
684             LERROR << "Error parsing root";
685             break;
686         }
687 
688         char* p;
689         if (!(p = strtok_r(nullptr, delim, &save_ptr))) {
690             LERROR << "Error parsing mount_point";
691             break;
692         }
693         mount_info entry = {p, false};
694 
695         if (!strtok_r(nullptr, delim, &save_ptr)) {
696             LERROR << "Error parsing mount_flags";
697             break;
698         }
699 
700         while ((p = strtok_r(nullptr, delim, &save_ptr))) {
701             if ((p[0] == '-') && (p[1] == '\0')) break;
702             if (android::base::StartsWith(p, "shared:")) entry.shared_flag = true;
703         }
704         if (!p) {
705             LERROR << "Error parsing fields";
706             break;
707         }
708         info.emplace_back(std::move(entry));
709     }
710 
711     free(line);
712     if (info.empty()) {
713         LERROR << __FUNCTION__ << "(): failed to load mountinfo from : '" << path << "'";
714     }
715     return info;
716 }
717 
fs_mgr_overlayfs_mount(const FstabEntry & entry)718 bool fs_mgr_overlayfs_mount(const FstabEntry& entry) {
719     const auto mount_point = fs_mgr_mount_point(entry.mount_point);
720     const auto options = fs_mgr_get_overlayfs_options(entry);
721     if (options.empty()) return false;
722 
723     auto retval = true;
724 
725     struct move_entry {
726         std::string mount_point;
727         std::string dir;
728         bool shared_flag;
729     };
730     std::vector<move_entry> move;
731     auto parent_private = false;
732     auto parent_made_private = false;
733     auto dev_private = false;
734     auto dev_made_private = false;
735     for (auto& entry : ReadMountinfoFromFile("/proc/self/mountinfo")) {
736         if ((entry.mount_point == mount_point) && !entry.shared_flag) {
737             parent_private = true;
738         }
739         if ((entry.mount_point == "/dev") && !entry.shared_flag) {
740             dev_private = true;
741         }
742 
743         if (!android::base::StartsWith(entry.mount_point, mount_point + "/")) {
744             continue;
745         }
746         if (std::find_if(move.begin(), move.end(), [&entry](const auto& it) {
747                 return android::base::StartsWith(entry.mount_point, it.mount_point + "/");
748             }) != move.end()) {
749             continue;
750         }
751 
752         // use as the bound directory in /dev.
753         AutoSetFsCreateCon createcon;
754         auto new_context = fs_mgr_get_context(entry.mount_point);
755         if (new_context.empty() || !createcon.Set(new_context)) {
756             continue;
757         }
758         move_entry new_entry = {std::move(entry.mount_point), "/dev/TemporaryDir-XXXXXX",
759                                 entry.shared_flag};
760         const auto target = mkdtemp(new_entry.dir.data());
761         if (!createcon.Restore()) {
762             return false;
763         }
764         if (!target) {
765             retval = false;
766             PERROR << "temporary directory for MS_BIND";
767             continue;
768         }
769 
770         if (!parent_private && !parent_made_private) {
771             parent_made_private = fs_mgr_overlayfs_set_shared_mount(mount_point, false);
772         }
773         if (new_entry.shared_flag) {
774             new_entry.shared_flag = fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, false);
775         }
776         if (!fs_mgr_overlayfs_move_mount(new_entry.mount_point, new_entry.dir)) {
777             retval = false;
778             if (new_entry.shared_flag) {
779                 fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, true);
780             }
781             continue;
782         }
783         move.emplace_back(std::move(new_entry));
784     }
785 
786     // hijack __mount() report format to help triage
787     auto report = "__mount(source=overlay,target="s + mount_point + ",type=overlay";
788     const auto opt_list = android::base::Split(options, ",");
789     for (const auto& opt : opt_list) {
790         if (android::base::StartsWith(opt, kUpperdirOption)) {
791             report = report + "," + opt;
792             break;
793         }
794     }
795     report = report + ")=";
796 
797     auto ret = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
798                      options.c_str());
799     if (ret) {
800         retval = false;
801         PERROR << report << ret;
802     } else {
803         LINFO << report << ret;
804     }
805 
806     // Move submounts back.
807     for (const auto& entry : move) {
808         if (!dev_private && !dev_made_private) {
809             dev_made_private = fs_mgr_overlayfs_set_shared_mount("/dev", false);
810         }
811 
812         if (!fs_mgr_overlayfs_move_mount(entry.dir, entry.mount_point)) {
813             retval = false;
814         } else if (entry.shared_flag &&
815                    !fs_mgr_overlayfs_set_shared_mount(entry.mount_point, true)) {
816             retval = false;
817         }
818         rmdir(entry.dir.c_str());
819     }
820     if (dev_made_private) {
821         fs_mgr_overlayfs_set_shared_mount("/dev", true);
822     }
823     if (parent_made_private) {
824         fs_mgr_overlayfs_set_shared_mount(mount_point, true);
825     }
826 
827     return retval;
828 }
829 
830 // Mount kScratchMountPoint
MountScratch(const std::string & device_path,bool readonly=false)831 bool MountScratch(const std::string& device_path, bool readonly = false) {
832     if (readonly) {
833         if (!fs_mgr_access(device_path)) {
834             LOG(ERROR) << "Path does not exist: " << device_path;
835             return false;
836         }
837     } else if (!fs_mgr_rw_access(device_path)) {
838         LOG(ERROR) << "Path does not exist or is not readwrite: " << device_path;
839         return false;
840     }
841 
842     std::vector<const char*> filesystem_candidates;
843     if (fs_mgr_is_f2fs(device_path)) {
844         filesystem_candidates = {"f2fs", "ext4"};
845     } else if (fs_mgr_is_ext4(device_path)) {
846         filesystem_candidates = {"ext4", "f2fs"};
847     } else {
848         LOG(ERROR) << "Scratch partition is not f2fs or ext4";
849         return false;
850     }
851 
852     AutoSetFsCreateCon createcon(kOverlayfsFileContext);
853     if (!createcon.Ok()) {
854         return false;
855     }
856     if (mkdir(kScratchMountPoint.c_str(), 0755) && (errno != EEXIST)) {
857         PERROR << "create " << kScratchMountPoint;
858         return false;
859     }
860 
861     FstabEntry entry;
862     entry.blk_device = device_path;
863     entry.mount_point = kScratchMountPoint;
864     entry.flags = MS_NOATIME | MS_RDONLY;
865     if (!readonly) {
866         entry.flags &= ~MS_RDONLY;
867         entry.flags |= MS_SYNCHRONOUS;
868         entry.fs_options = "nodiscard";
869         fs_mgr_set_blk_ro(device_path, false);
870     }
871     // check_fs requires apex runtime library
872     if (fs_mgr_overlayfs_already_mounted("/data", false)) {
873         entry.fs_mgr_flags.check = true;
874     }
875     bool mounted = false;
876     for (auto fs_type : filesystem_candidates) {
877         entry.fs_type = fs_type;
878         if (fs_mgr_do_mount_one(entry) == 0) {
879             mounted = true;
880             break;
881         }
882     }
883     if (!createcon.Restore()) {
884         return false;
885     }
886     if (!mounted) {
887         rmdir(kScratchMountPoint.c_str());
888         return false;
889     }
890     return true;
891 }
892 
893 const std::string kMkF2fs("/system/bin/make_f2fs");
894 const std::string kMkExt4("/system/bin/mke2fs");
895 
896 // Note: The scratch partition of DSU is managed by gsid, and should be initialized during
897 // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
GetDsuScratchDevice()898 static std::string GetDsuScratchDevice() {
899     auto& dm = DeviceMapper::Instance();
900     std::string device;
901     if (dm.GetState(android::gsi::kDsuScratch) != DmDeviceState::INVALID &&
902         dm.GetDmDevicePathByName(android::gsi::kDsuScratch, &device)) {
903         return device;
904     }
905     return "";
906 }
907 
908 // This returns the scratch device that was detected during early boot (first-
909 // stage init). If the device was created later, for example during setup for
910 // the adb remount command, it can return an empty string since it does not
911 // query ImageManager. (Note that ImageManager in first-stage init will always
912 // use device-mapper, since /data is not available to use loop devices.)
GetBootScratchDevice()913 static std::string GetBootScratchDevice() {
914     // Note: fs_mgr_is_dsu_running() always returns false in recovery or fastbootd.
915     if (fs_mgr_is_dsu_running()) {
916         return GetDsuScratchDevice();
917     }
918 
919     auto& dm = DeviceMapper::Instance();
920 
921     // If there is a scratch partition allocated in /data or on super, we
922     // automatically prioritize that over super_other or system_other.
923     // Some devices, for example, have a write-protected eMMC and the
924     // super partition cannot be used even if it exists.
925     std::string device;
926     auto partition_name = android::base::Basename(kScratchMountPoint);
927     if (dm.GetState(partition_name) != DmDeviceState::INVALID &&
928         dm.GetDmDevicePathByName(partition_name, &device)) {
929         return device;
930     }
931 
932     return "";
933 }
934 
MakeScratchFilesystem(const std::string & scratch_device)935 bool MakeScratchFilesystem(const std::string& scratch_device) {
936     // Force mkfs by design for overlay support of adb remount, simplify and
937     // thus do not rely on fsck to correct problems that could creep in.
938     auto fs_type = ""s;
939     auto command = ""s;
940     if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) {
941         fs_type = "f2fs";
942         command = kMkF2fs + " -w 4096 -f -d1 -l" + android::base::Basename(kScratchMountPoint);
943     } else if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) {
944         fs_type = "ext4";
945         command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
946     } else {
947         LERROR << "No supported mkfs command or filesystem driver available, supported filesystems "
948                   "are: f2fs, ext4";
949         return false;
950     }
951     command += " " + scratch_device + " >/dev/null 2>/dev/null </dev/null";
952     fs_mgr_set_blk_ro(scratch_device, false);
953     auto ret = system(command.c_str());
954     if (ret) {
955         LERROR << "make " << fs_type << " filesystem on " << scratch_device << " return=" << ret;
956         return false;
957     }
958     return true;
959 }
960 
TruncatePartitionsWithSuffix(MetadataBuilder * builder,const std::string & suffix)961 static void TruncatePartitionsWithSuffix(MetadataBuilder* builder, const std::string& suffix) {
962     auto& dm = DeviceMapper::Instance();
963 
964     // Remove <other> partitions
965     for (const auto& group : builder->ListGroups()) {
966         for (const auto& part : builder->ListPartitionsInGroup(group)) {
967             const auto& name = part->name();
968             if (!android::base::EndsWith(name, suffix)) {
969                 continue;
970             }
971             if (dm.GetState(name) != DmDeviceState::INVALID && !DestroyLogicalPartition(name)) {
972                 continue;
973             }
974             builder->ResizePartition(builder->FindPartition(name), 0);
975         }
976     }
977 }
978 
979 // Create or update a scratch partition within super.
CreateDynamicScratch(std::string * scratch_device,bool * partition_exists)980 static bool CreateDynamicScratch(std::string* scratch_device, bool* partition_exists) {
981     const auto partition_name = android::base::Basename(kScratchMountPoint);
982 
983     auto& dm = DeviceMapper::Instance();
984     *partition_exists = dm.GetState(partition_name) != DmDeviceState::INVALID;
985 
986     auto partition_create = !*partition_exists;
987     auto slot_number = fs_mgr_overlayfs_slot_number();
988     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
989     auto builder = MetadataBuilder::New(super_device, slot_number);
990     if (!builder) {
991         LERROR << "open " << super_device << " metadata";
992         return false;
993     }
994     auto partition = builder->FindPartition(partition_name);
995     *partition_exists = partition != nullptr;
996     auto changed = false;
997     if (!*partition_exists) {
998         partition = builder->AddPartition(partition_name, LP_PARTITION_ATTR_NONE);
999         if (!partition) {
1000             LERROR << "create " << partition_name;
1001             return false;
1002         }
1003         changed = true;
1004     }
1005     // Take half of free space, minimum 512MB or maximum free - margin.
1006     static constexpr auto kMinimumSize = uint64_t(512 * 1024 * 1024);
1007     if (partition->size() < kMinimumSize) {
1008         auto partition_size =
1009                 builder->AllocatableSpace() - builder->UsedSpace() + partition->size();
1010         if ((partition_size > kMinimumSize) || !partition->size()) {
1011             // Leave some space for free space jitter of a few erase
1012             // blocks, in case they are needed for any individual updates
1013             // to any other partition that needs to be flashed while
1014             // overlayfs is in force.  Of course if margin_size is not
1015             // enough could normally get a flash failure, so
1016             // ResizePartition() will delete the scratch partition in
1017             // order to fulfill.  Deleting scratch will destroy all of
1018             // the adb remount overrides :-( .
1019             auto margin_size = uint64_t(3 * 256 * 1024);
1020             BlockDeviceInfo info;
1021             if (builder->GetBlockDeviceInfo(fs_mgr_get_super_partition_name(slot_number), &info)) {
1022                 margin_size = 3 * info.logical_block_size;
1023             }
1024             partition_size = std::max(std::min(kMinimumSize, partition_size - margin_size),
1025                                       partition_size / 2);
1026             if (partition_size > partition->size()) {
1027                 if (!builder->ResizePartition(partition, partition_size)) {
1028                     // Try to free up space by deallocating partitions in the other slot.
1029                     TruncatePartitionsWithSuffix(builder.get(), fs_mgr_get_other_slot_suffix());
1030 
1031                     partition_size =
1032                             builder->AllocatableSpace() - builder->UsedSpace() + partition->size();
1033                     partition_size = std::max(std::min(kMinimumSize, partition_size - margin_size),
1034                                               partition_size / 2);
1035                     if (!builder->ResizePartition(partition, partition_size)) {
1036                         LERROR << "resize " << partition_name;
1037                         return false;
1038                     }
1039                 }
1040                 if (!partition_create) DestroyLogicalPartition(partition_name);
1041                 changed = true;
1042                 *partition_exists = false;
1043             }
1044         }
1045     }
1046     // land the update back on to the partition
1047     if (changed) {
1048         auto metadata = builder->Export();
1049         if (!metadata || !UpdatePartitionTable(super_device, *metadata.get(), slot_number)) {
1050             LERROR << "add partition " << partition_name;
1051             return false;
1052         }
1053     }
1054 
1055     if (changed || partition_create) {
1056         CreateLogicalPartitionParams params = {
1057                 .block_device = super_device,
1058                 .metadata_slot = slot_number,
1059                 .partition_name = partition_name,
1060                 .force_writable = true,
1061                 .timeout_ms = 10s,
1062         };
1063         if (!CreateLogicalPartition(params, scratch_device)) {
1064             return false;
1065         }
1066     } else if (scratch_device->empty()) {
1067         *scratch_device = GetBootScratchDevice();
1068     }
1069     return true;
1070 }
1071 
GetIdealDataScratchSize()1072 static inline uint64_t GetIdealDataScratchSize() {
1073     BlockDeviceInfo super_info;
1074     PartitionOpener opener;
1075     if (!opener.GetInfo(fs_mgr_get_super_partition_name(), &super_info)) {
1076         LERROR << "could not get block device info for super";
1077         return 0;
1078     }
1079 
1080     struct statvfs s;
1081     if (statvfs("/data", &s) < 0) {
1082         PERROR << "could not statfs /data";
1083         return 0;
1084     }
1085 
1086     auto ideal_size = std::min(super_info.size, (uint64_t(s.f_frsize) * s.f_bfree) / 2);
1087 
1088     // Align up to the filesystem block size.
1089     if (auto remainder = ideal_size % s.f_bsize; remainder > 0) {
1090         ideal_size += s.f_bsize - remainder;
1091     }
1092     return ideal_size;
1093 }
1094 
CreateScratchOnData(std::string * scratch_device,bool * partition_exists)1095 static bool CreateScratchOnData(std::string* scratch_device, bool* partition_exists) {
1096     *partition_exists = false;
1097 
1098     auto images = IImageManager::Open("remount", 10s);
1099     if (!images) {
1100         return false;
1101     }
1102 
1103     auto partition_name = android::base::Basename(kScratchMountPoint);
1104     if (images->GetMappedImageDevice(partition_name, scratch_device)) {
1105         *partition_exists = true;
1106         return true;
1107     }
1108 
1109     // Note: calling RemoveDisabledImages here ensures that we do not race with
1110     // clean_scratch_files and accidentally try to map an image that will be
1111     // deleted.
1112     if (!images->RemoveDisabledImages()) {
1113         return false;
1114     }
1115     if (!images->BackingImageExists(partition_name)) {
1116         auto size = android::base::GetUintProperty<uint64_t>(kDataScratchSizeMbProp, 0) * 1_MiB;
1117         if (!size) {
1118             size = GetIdealDataScratchSize();
1119         }
1120         if (!size) {
1121             size = 2_GiB;
1122         }
1123 
1124         auto flags = IImageManager::CREATE_IMAGE_DEFAULT;
1125 
1126         if (!images->CreateBackingImage(partition_name, size, flags)) {
1127             LERROR << "could not create scratch image of " << size << " bytes";
1128             return false;
1129         }
1130     }
1131     if (!images->MapImageDevice(partition_name, 10s, scratch_device)) {
1132         LERROR << "could not map scratch image";
1133         // If we cannot use this image, then remove it.
1134         TeardownDataScratch(images.get(), partition_name, false /* was_mounted */);
1135         return false;
1136     }
1137     return true;
1138 }
1139 
CanUseSuperPartition(const Fstab & fstab)1140 static bool CanUseSuperPartition(const Fstab& fstab) {
1141     auto slot_number = fs_mgr_overlayfs_slot_number();
1142     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
1143     if (!fs_mgr_rw_access(super_device) || !fs_mgr_overlayfs_has_logical(fstab)) {
1144         return false;
1145     }
1146     auto metadata = ReadMetadata(super_device, slot_number);
1147     if (!metadata) {
1148         return false;
1149     }
1150     return true;
1151 }
1152 
fs_mgr_overlayfs_create_scratch(const Fstab & fstab,std::string * scratch_device,bool * partition_exists)1153 bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device,
1154                                      bool* partition_exists) {
1155     // Use the DSU scratch device managed by gsid if within a DSU system.
1156     if (fs_mgr_is_dsu_running()) {
1157         *scratch_device = GetDsuScratchDevice();
1158         *partition_exists = !scratch_device->empty();
1159         return *partition_exists;
1160     }
1161 
1162     // Try ImageManager on /data first.
1163     bool can_use_data = false;
1164     if (FilesystemHasReliablePinning("/data", &can_use_data) && can_use_data) {
1165         if (CreateScratchOnData(scratch_device, partition_exists)) {
1166             return true;
1167         }
1168         LOG(WARNING) << "Failed to allocate scratch on /data, fallback to use free space on super";
1169     }
1170     // If that fails, see if we can land on super.
1171     if (CanUseSuperPartition(fstab)) {
1172         return CreateDynamicScratch(scratch_device, partition_exists);
1173     }
1174     return false;
1175 }
1176 
1177 // Create and mount kScratchMountPoint storage if we have logical partitions
fs_mgr_overlayfs_setup_scratch(const Fstab & fstab)1178 bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) {
1179     if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
1180         return true;
1181     }
1182 
1183     std::string scratch_device;
1184     bool partition_exists;
1185     if (!fs_mgr_overlayfs_create_scratch(fstab, &scratch_device, &partition_exists)) {
1186         LOG(ERROR) << "Failed to create scratch partition";
1187         return false;
1188     }
1189 
1190     // If the partition exists, assume first that it can be mounted.
1191     if (partition_exists) {
1192         if (MountScratch(scratch_device)) {
1193             if (fs_mgr_access(kScratchMountPoint + kOverlayTopDir) ||
1194                 fs_mgr_filesystem_has_space(kScratchMountPoint)) {
1195                 return true;
1196             }
1197             // declare it useless, no overrides and no free space
1198             if (!fs_mgr_overlayfs_umount_scratch()) {
1199                 LOG(ERROR) << "Unable to unmount scratch partition";
1200                 return false;
1201             }
1202         }
1203     }
1204 
1205     if (!MakeScratchFilesystem(scratch_device)) {
1206         LOG(ERROR) << "Failed to format scratch partition";
1207         return false;
1208     }
1209 
1210     return MountScratch(scratch_device);
1211 }
1212 
1213 #if ALLOW_ADBD_DISABLE_VERITY
1214 constexpr bool kAllowOverlayfs = true;
1215 #else
1216 constexpr bool kAllowOverlayfs = false;
1217 #endif
1218 
1219 // NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
1220 // Setup is allowed only if teardown is also allowed.
OverlayfsSetupAllowed(bool verbose=false)1221 bool OverlayfsSetupAllowed(bool verbose = false) {
1222     if (!kAllowOverlayfs) {
1223         if (verbose) {
1224             LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
1225         }
1226         return false;
1227     }
1228     // Check mandatory kernel patches.
1229     if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
1230         if (verbose) {
1231             LOG(ERROR) << "Kernel does not support overlayfs";
1232         }
1233         return false;
1234     }
1235     // in recovery or fastbootd, not allowed!
1236     if (fs_mgr_in_recovery()) {
1237         if (verbose) {
1238             LOG(ERROR) << "Unsupported overlayfs setup from recovery";
1239         }
1240         return false;
1241     }
1242     return true;
1243 }
1244 
OverlayfsTeardownAllowed()1245 constexpr bool OverlayfsTeardownAllowed() {
1246     // Never allow on non-debuggable build.
1247     return kAllowOverlayfs;
1248 }
1249 
1250 }  // namespace
1251 
fs_mgr_wants_overlayfs(FstabEntry * entry)1252 bool fs_mgr_wants_overlayfs(FstabEntry* entry) {
1253     // Don't check entries that are managed by vold.
1254     if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false;
1255 
1256     // *_other doesn't want overlayfs.
1257     if (entry->fs_mgr_flags.slot_select_other) return false;
1258 
1259     // Only concerned with readonly partitions.
1260     if (!(entry->flags & MS_RDONLY)) return false;
1261 
1262     // If unbindable, do not allow overlayfs as this could expose us to
1263     // security issues.  On Android, this could also be used to turn off
1264     // the ability to overlay an otherwise acceptable filesystem since
1265     // /system and /vendor are never bound(sic) to.
1266     if (entry->flags & MS_UNBINDABLE) return false;
1267 
1268     if (!fs_mgr_overlayfs_enabled(entry)) return false;
1269 
1270     return true;
1271 }
1272 
fs_mgr_overlayfs_candidate_list(const Fstab & fstab)1273 Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) {
1274     android::fs_mgr::Fstab mounts;
1275     if (!android::fs_mgr::ReadFstabFromFile("/proc/mounts", &mounts)) {
1276         PLOG(ERROR) << "Failed to read /proc/mounts";
1277         return {};
1278     }
1279 
1280     Fstab candidates;
1281     for (const auto& entry : fstab) {
1282         // Filter out partitions whose type doesn't match what's mounted.
1283         // This avoids spammy behavior on devices which can mount different
1284         // filesystems for each partition.
1285         auto proc_mount_point = (entry.mount_point == "/system") ? "/" : entry.mount_point;
1286         auto mounted = GetEntryForMountPoint(&mounts, proc_mount_point);
1287         if (!mounted || mounted->fs_type != entry.fs_type) {
1288             continue;
1289         }
1290 
1291         FstabEntry new_entry = entry;
1292         if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) &&
1293             !fs_mgr_wants_overlayfs(&new_entry)) {
1294             continue;
1295         }
1296         auto new_mount_point = fs_mgr_mount_point(entry.mount_point);
1297         auto duplicate_or_more_specific = false;
1298         for (auto it = candidates.begin(); it != candidates.end();) {
1299             auto it_mount_point = fs_mgr_mount_point(it->mount_point);
1300             if ((it_mount_point == new_mount_point) ||
1301                 (android::base::StartsWith(new_mount_point, it_mount_point + "/"))) {
1302                 duplicate_or_more_specific = true;
1303                 break;
1304             }
1305             if (android::base::StartsWith(it_mount_point, new_mount_point + "/")) {
1306                 it = candidates.erase(it);
1307             } else {
1308                 ++it;
1309             }
1310         }
1311         if (!duplicate_or_more_specific) candidates.emplace_back(std::move(new_entry));
1312     }
1313     return candidates;
1314 }
1315 
TryMountScratch()1316 static void TryMountScratch() {
1317     // Note we get the boot scratch device here, which means if scratch was
1318     // just created through ImageManager, this could fail. In practice this
1319     // should not happen because "remount" detects this scenario (by checking
1320     // if verity is still disabled, i.e. no reboot occurred), and skips calling
1321     // fs_mgr_overlayfs_mount_all().
1322     auto scratch_device = GetBootScratchDevice();
1323     if (!fs_mgr_rw_access(scratch_device)) {
1324         return;
1325     }
1326     if (!WaitForFile(scratch_device, 10s)) {
1327         return;
1328     }
1329     if (!MountScratch(scratch_device, true /* readonly */)) {
1330         return;
1331     }
1332     auto has_overlayfs_dir = fs_mgr_access(kScratchMountPoint + kOverlayTopDir);
1333     fs_mgr_overlayfs_umount_scratch();
1334     if (has_overlayfs_dir) {
1335         MountScratch(scratch_device);
1336     }
1337 }
1338 
fs_mgr_overlayfs_mount_all(Fstab * fstab)1339 bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
1340     if (!OverlayfsSetupAllowed()) {
1341         return false;
1342     }
1343     auto ret = true;
1344     auto scratch_can_be_mounted = true;
1345     for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) {
1346         if (fs_mgr_is_verity_enabled(entry)) continue;
1347         auto mount_point = fs_mgr_mount_point(entry.mount_point);
1348         if (fs_mgr_overlayfs_already_mounted(mount_point)) {
1349             continue;
1350         }
1351         if (scratch_can_be_mounted) {
1352             scratch_can_be_mounted = false;
1353             TryMountScratch();
1354         }
1355         ret &= fs_mgr_overlayfs_mount(entry);
1356     }
1357     return ret;
1358 }
1359 
fs_mgr_overlayfs_setup(const Fstab & fstab,const char * mount_point,bool * want_reboot,bool just_disabled_verity)1360 bool fs_mgr_overlayfs_setup(const Fstab& fstab, const char* mount_point, bool* want_reboot,
1361                             bool just_disabled_verity) {
1362     if (!OverlayfsSetupAllowed(/*verbose=*/true)) {
1363         return false;
1364     }
1365 
1366     if (!fs_mgr_boot_completed()) {
1367         LOG(ERROR) << "Cannot setup overlayfs before persistent properties are ready";
1368         return false;
1369     }
1370 
1371     auto candidates = fs_mgr_overlayfs_candidate_list(fstab);
1372     for (auto it = candidates.begin(); it != candidates.end();) {
1373         if (mount_point &&
1374             (fs_mgr_mount_point(it->mount_point) != fs_mgr_mount_point(mount_point))) {
1375             it = candidates.erase(it);
1376             continue;
1377         }
1378 
1379         auto verity_enabled = !just_disabled_verity && fs_mgr_is_verity_enabled(*it);
1380         if (verity_enabled) {
1381             it = candidates.erase(it);
1382             continue;
1383         }
1384         ++it;
1385     }
1386 
1387     if (candidates.empty()) {
1388         if (mount_point) {
1389             LOG(ERROR) << "No overlayfs candidate was found for " << mount_point;
1390             return false;
1391         }
1392         return true;
1393     }
1394 
1395     std::string dir;
1396     for (const auto& overlay_mount_point : OverlayMountPoints()) {
1397         if (overlay_mount_point == kScratchMountPoint) {
1398             if (!fs_mgr_overlayfs_setup_scratch(fstab)) {
1399                 continue;
1400             }
1401         } else {
1402             if (GetEntryForMountPoint(&fstab, overlay_mount_point) == nullptr) {
1403                 continue;
1404             }
1405         }
1406         dir = overlay_mount_point;
1407         break;
1408     }
1409     if (dir.empty()) {
1410         LOG(ERROR) << "Could not allocate backing storage for overlays";
1411         return false;
1412     }
1413 
1414     const auto overlay = fs_mgr_overlayfs_setup_dir(dir);
1415     if (overlay.empty()) {
1416         return false;
1417     }
1418 
1419     bool ok = true;
1420     for (const auto& entry : candidates) {
1421         auto fstab_mount_point = fs_mgr_mount_point(entry.mount_point);
1422         ok &= fs_mgr_overlayfs_setup_one(overlay, fstab_mount_point, want_reboot);
1423     }
1424     return ok;
1425 }
1426 
1427 struct MapInfo {
1428     // If set, partition is owned by ImageManager.
1429     std::unique_ptr<IImageManager> images;
1430     // If set, and images is null, this is a DAP partition.
1431     std::string name;
1432     // If set, and images and name are empty, this is a non-dynamic partition.
1433     std::string device;
1434 
1435     MapInfo() = default;
1436     MapInfo(MapInfo&&) = default;
~MapInfoMapInfo1437     ~MapInfo() {
1438         if (images) {
1439             images->UnmapImageDevice(name);
1440         } else if (!name.empty()) {
1441             DestroyLogicalPartition(name);
1442         }
1443     }
1444 };
1445 
1446 // Note: This function never returns the DSU scratch device in recovery or fastbootd,
1447 // because the DSU scratch is created in the first-stage-mount, which is not run in recovery.
EnsureScratchMapped()1448 static std::optional<MapInfo> EnsureScratchMapped() {
1449     MapInfo info;
1450     info.device = GetBootScratchDevice();
1451     if (!info.device.empty()) {
1452         return {std::move(info)};
1453     }
1454     if (!fs_mgr_in_recovery()) {
1455         return {};
1456     }
1457 
1458     auto partition_name = android::base::Basename(kScratchMountPoint);
1459 
1460     // Check for scratch on /data first, before looking for a modified super
1461     // partition. We should only reach this code in recovery, because scratch
1462     // would otherwise always be mapped.
1463     auto images = IImageManager::Open("remount", 10s);
1464     if (images && images->BackingImageExists(partition_name)) {
1465         if (images->IsImageDisabled(partition_name)) {
1466             return {};
1467         }
1468         if (!images->MapImageDevice(partition_name, 10s, &info.device)) {
1469             return {};
1470         }
1471         info.name = partition_name;
1472         info.images = std::move(images);
1473         return {std::move(info)};
1474     }
1475 
1476     // Avoid uart spam by first checking for a scratch partition.
1477     auto metadata_slot = fs_mgr_overlayfs_slot_number();
1478     auto super_device = fs_mgr_overlayfs_super_device(metadata_slot);
1479     auto metadata = ReadCurrentMetadata(super_device);
1480     if (!metadata) {
1481         return {};
1482     }
1483 
1484     auto partition = FindPartition(*metadata.get(), partition_name);
1485     if (!partition) {
1486         return {};
1487     }
1488 
1489     CreateLogicalPartitionParams params = {
1490             .block_device = super_device,
1491             .metadata = metadata.get(),
1492             .partition = partition,
1493             .force_writable = true,
1494             .timeout_ms = 10s,
1495     };
1496     if (!CreateLogicalPartition(params, &info.device)) {
1497         return {};
1498     }
1499     info.name = partition_name;
1500     return {std::move(info)};
1501 }
1502 
1503 // This should only be reachable in recovery, where DSU scratch is not
1504 // automatically mapped.
MapDsuScratchDevice(std::string * device)1505 static bool MapDsuScratchDevice(std::string* device) {
1506     std::string dsu_slot;
1507     if (!android::gsi::IsGsiInstalled() || !android::gsi::GetActiveDsu(&dsu_slot) ||
1508         dsu_slot.empty()) {
1509         // Nothing to do if no DSU installation present.
1510         return false;
1511     }
1512 
1513     auto images = IImageManager::Open("dsu/" + dsu_slot, 10s);
1514     if (!images || !images->BackingImageExists(android::gsi::kDsuScratch)) {
1515         // Nothing to do if DSU scratch device doesn't exist.
1516         return false;
1517     }
1518 
1519     images->UnmapImageDevice(android::gsi::kDsuScratch);
1520     if (!images->MapImageDevice(android::gsi::kDsuScratch, 10s, device)) {
1521         return false;
1522     }
1523     return true;
1524 }
1525 
TeardownMountsAndScratch(const char * mount_point,bool * want_reboot)1526 static OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point,
1527                                                         bool* want_reboot) {
1528     bool should_destroy_scratch = false;
1529     auto rv = OverlayfsTeardownResult::Ok;
1530     for (const auto& overlay_mount_point : OverlayMountPoints()) {
1531         auto ok = fs_mgr_overlayfs_teardown_one(
1532                 overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "",
1533                 want_reboot,
1534                 overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr);
1535         if (!ok) {
1536             rv = OverlayfsTeardownResult::Error;
1537         }
1538     }
1539 
1540     // Do not attempt to destroy DSU scratch if within a DSU system,
1541     // because DSU scratch partition is managed by gsid.
1542     if (should_destroy_scratch && !fs_mgr_is_dsu_running()) {
1543         auto rv = fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, want_reboot);
1544         if (rv != OverlayfsTeardownResult::Ok) {
1545             return rv;
1546         }
1547     }
1548     // And now that we did what we could, lets inform
1549     // caller that there may still be more to do.
1550     if (!fs_mgr_boot_completed()) {
1551         LOG(ERROR) << "Cannot teardown overlayfs before persistent properties are ready";
1552         return OverlayfsTeardownResult::Error;
1553     }
1554     return rv;
1555 }
1556 
1557 // Returns false if teardown not permitted. If something is altered, set *want_reboot.
fs_mgr_overlayfs_teardown(const char * mount_point,bool * want_reboot)1558 OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* want_reboot) {
1559     if (!OverlayfsTeardownAllowed()) {
1560         // Nothing to teardown.
1561         return OverlayfsTeardownResult::Ok;
1562     }
1563     // If scratch exists, but is not mounted, lets gain access to clean
1564     // specific override entries.
1565     auto mount_scratch = false;
1566     if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
1567         std::string scratch_device = GetBootScratchDevice();
1568         if (!scratch_device.empty()) {
1569             mount_scratch = MountScratch(scratch_device);
1570         }
1571     }
1572 
1573     auto rv = TeardownMountsAndScratch(mount_point, want_reboot);
1574 
1575     if (mount_scratch) {
1576         if (!fs_mgr_overlayfs_umount_scratch()) {
1577             return OverlayfsTeardownResult::Busy;
1578         }
1579     }
1580     return rv;
1581 }
1582 
fs_mgr_overlayfs_is_setup()1583 bool fs_mgr_overlayfs_is_setup() {
1584     if (!OverlayfsSetupAllowed()) {
1585         return false;
1586     }
1587     if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
1588     Fstab fstab;
1589     if (!ReadDefaultFstab(&fstab)) {
1590         return false;
1591     }
1592     for (const auto& entry : fs_mgr_overlayfs_candidate_list(fstab)) {
1593         if (fs_mgr_is_verity_enabled(entry)) continue;
1594         if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) return true;
1595     }
1596     return false;
1597 }
1598 
1599 namespace android {
1600 namespace fs_mgr {
1601 
MapScratchPartitionIfNeeded(Fstab * fstab,const std::function<bool (const std::set<std::string> &)> & init)1602 void MapScratchPartitionIfNeeded(Fstab* fstab,
1603                                  const std::function<bool(const std::set<std::string>&)>& init) {
1604     if (!OverlayfsSetupAllowed()) {
1605         return;
1606     }
1607     if (GetEntryForMountPoint(fstab, kScratchMountPoint) != nullptr) {
1608         return;
1609     }
1610 
1611     bool want_scratch = false;
1612     for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) {
1613         if (fs_mgr_is_verity_enabled(entry)) {
1614             continue;
1615         }
1616         if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) {
1617             continue;
1618         }
1619         want_scratch = true;
1620         break;
1621     }
1622     if (!want_scratch) {
1623         return;
1624     }
1625 
1626     if (ScratchIsOnData()) {
1627         if (auto images = IImageManager::Open("remount", 0ms)) {
1628             images->MapAllImages(init);
1629         }
1630     }
1631 
1632     // Physical or logical partitions will have already been mapped here,
1633     // so just ensure /dev/block symlinks exist.
1634     auto device = GetBootScratchDevice();
1635     if (!device.empty()) {
1636         init({android::base::Basename(device)});
1637     }
1638 }
1639 
CleanupOldScratchFiles()1640 void CleanupOldScratchFiles() {
1641     if (!OverlayfsTeardownAllowed()) {
1642         return;
1643     }
1644     if (!ScratchIsOnData()) {
1645         return;
1646     }
1647     if (auto images = IImageManager::Open("remount", 0ms)) {
1648         images->RemoveDisabledImages();
1649     }
1650 }
1651 
TeardownAllOverlayForMountPoint(const std::string & mount_point)1652 void TeardownAllOverlayForMountPoint(const std::string& mount_point) {
1653     if (!OverlayfsTeardownAllowed()) {
1654         return;
1655     }
1656     if (!fs_mgr_in_recovery()) {
1657         LERROR << __FUNCTION__ << "(): must be called within recovery.";
1658         return;
1659     }
1660 
1661     // Empty string means teardown everything.
1662     const std::string teardown_dir = mount_point.empty() ? "" : fs_mgr_mount_point(mount_point);
1663     constexpr bool* ignore_change = nullptr;
1664 
1665     // Teardown legacy overlay mount points that's not backed by a scratch device.
1666     for (const auto& overlay_mount_point : OverlayMountPoints()) {
1667         if (overlay_mount_point == kScratchMountPoint) {
1668             continue;
1669         }
1670         fs_mgr_overlayfs_teardown_one(overlay_mount_point, teardown_dir, ignore_change);
1671     }
1672 
1673     if (mount_point.empty()) {
1674         // Throw away the entire partition.
1675         auto partition_name = android::base::Basename(kScratchMountPoint);
1676         auto images = IImageManager::Open("remount", 10s);
1677         if (images && images->BackingImageExists(partition_name)) {
1678             if (images->DisableImage(partition_name)) {
1679                 LOG(INFO) << "Disabled scratch partition for: " << kScratchMountPoint;
1680             } else {
1681                 LOG(ERROR) << "Unable to disable scratch partition for " << kScratchMountPoint;
1682             }
1683         }
1684     }
1685 
1686     // Note if we just disabled scratch, this mount will fail.
1687     if (auto info = EnsureScratchMapped(); info.has_value()) {
1688         // Map scratch device, mount kScratchMountPoint and teardown kScratchMountPoint.
1689         fs_mgr_overlayfs_umount_scratch();
1690         if (MountScratch(info->device)) {
1691             bool should_destroy_scratch = false;
1692             fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change,
1693                                           &should_destroy_scratch);
1694             fs_mgr_overlayfs_umount_scratch();
1695             if (should_destroy_scratch) {
1696                 fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, nullptr);
1697             }
1698         }
1699     }
1700 
1701     // Teardown DSU overlay if present.
1702     std::string scratch_device;
1703     if (MapDsuScratchDevice(&scratch_device)) {
1704         fs_mgr_overlayfs_umount_scratch();
1705         if (MountScratch(scratch_device)) {
1706             fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change);
1707             fs_mgr_overlayfs_umount_scratch();
1708         }
1709         DestroyLogicalPartition(android::gsi::kDsuScratch);
1710     }
1711 }
1712 
1713 }  // namespace fs_mgr
1714 }  // namespace android
1715 
fs_mgr_overlayfs_already_mounted(const std::string & mount_point,bool overlay_only)1716 bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only) {
1717     Fstab fstab;
1718     if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
1719         return false;
1720     }
1721     const auto lowerdir = kLowerdirOption + mount_point;
1722     for (const auto& entry : fstab) {
1723         if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
1724         if (mount_point != entry.mount_point) continue;
1725         if (!overlay_only) return true;
1726         const auto options = android::base::Split(entry.fs_options, ",");
1727         for (const auto& opt : options) {
1728             if (opt == lowerdir) {
1729                 return true;
1730             }
1731         }
1732     }
1733     return false;
1734 }
1735