• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <map>
36 #include <memory>
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_dm_linear.h>
48 #include <fs_mgr_overlayfs.h>
49 #include <fstab/fstab.h>
50 #include <libdm/dm.h>
51 #include <libgsi/libgsi.h>
52 #include <liblp/builder.h>
53 #include <liblp/liblp.h>
54 
55 #include "fs_mgr_priv.h"
56 
57 using namespace std::literals;
58 using namespace android::dm;
59 using namespace android::fs_mgr;
60 
61 namespace {
62 
fs_mgr_access(const std::string & path)63 bool fs_mgr_access(const std::string& path) {
64     auto save_errno = errno;
65     auto ret = access(path.c_str(), F_OK) == 0;
66     errno = save_errno;
67     return ret;
68 }
69 
70 // determine if a filesystem is available
fs_mgr_overlayfs_filesystem_available(const std::string & filesystem)71 bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) {
72     std::string filesystems;
73     if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false;
74     return filesystems.find("\t" + filesystem + "\n") != std::string::npos;
75 }
76 
77 }  // namespace
78 
79 #if ALLOW_ADBD_DISABLE_VERITY == 0  // If we are a user build, provide stubs
80 
fs_mgr_overlayfs_candidate_list(const Fstab &)81 Fstab fs_mgr_overlayfs_candidate_list(const Fstab&) {
82     return {};
83 }
84 
fs_mgr_overlayfs_mount_all(Fstab *)85 bool fs_mgr_overlayfs_mount_all(Fstab*) {
86     return false;
87 }
88 
fs_mgr_overlayfs_required_devices(Fstab *)89 std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab*) {
90     return {};
91 }
92 
fs_mgr_overlayfs_setup(const char *,const char *,bool * change,bool)93 bool fs_mgr_overlayfs_setup(const char*, const char*, bool* change, bool) {
94     if (change) *change = false;
95     return false;
96 }
97 
fs_mgr_overlayfs_teardown(const char *,bool * change)98 bool fs_mgr_overlayfs_teardown(const char*, bool* change) {
99     if (change) *change = false;
100     return false;
101 }
102 
fs_mgr_overlayfs_is_setup()103 bool fs_mgr_overlayfs_is_setup() {
104     return false;
105 }
106 
107 #else  // ALLOW_ADBD_DISABLE_VERITY == 0
108 
109 namespace {
110 
111 // list of acceptable overlayfs backing storage
112 const auto kScratchMountPoint = "/mnt/scratch"s;
113 const auto kCacheMountPoint = "/cache"s;
114 const std::vector<const std::string> kOverlayMountPoints = {kScratchMountPoint, kCacheMountPoint};
115 
116 // Return true if everything is mounted, but before adb is started.  Right
117 // after 'trigger load_persist_props_action' is done.
fs_mgr_boot_completed()118 bool fs_mgr_boot_completed() {
119     return android::base::GetBoolProperty("ro.persistent_properties.ready", false);
120 }
121 
fs_mgr_is_dir(const std::string & path)122 bool fs_mgr_is_dir(const std::string& path) {
123     struct stat st;
124     return !stat(path.c_str(), &st) && S_ISDIR(st.st_mode);
125 }
126 
127 // Similar test as overlayfs workdir= validation in the kernel for read-write
128 // validation, except we use fs_mgr_work.  Covers space and storage issues.
fs_mgr_dir_is_writable(const std::string & path)129 bool fs_mgr_dir_is_writable(const std::string& path) {
130     auto test_directory = path + "/fs_mgr_work";
131     rmdir(test_directory.c_str());
132     auto ret = !mkdir(test_directory.c_str(), 0700);
133     return ret | !rmdir(test_directory.c_str());
134 }
135 
136 // At less than 1% free space return value of false,
137 // means we will try to wrap with overlayfs.
fs_mgr_filesystem_has_space(const std::string & mount_point)138 bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
139     // If we have access issues to find out space remaining, return true
140     // to prevent us trying to override with overlayfs.
141     struct statvfs vst;
142     auto save_errno = errno;
143     if (statvfs(mount_point.c_str(), &vst)) {
144         errno = save_errno;
145         return true;
146     }
147 
148     static constexpr int kPercentThreshold = 1;  // 1%
149 
150     return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100));
151 }
152 
fs_mgr_overlayfs_enabled(FstabEntry * entry)153 bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
154     // readonly filesystem, can not be mount -o remount,rw
155     // for squashfs, erofs or if free space is (near) zero making such a remount
156     // virtually useless, or if there are shared blocks that prevent remount,rw
157     if (!fs_mgr_filesystem_has_space(entry->mount_point)) {
158         return true;
159     }
160     if (entry->fs_mgr_flags.logical) {
161         fs_mgr_update_logical_partition(entry);
162     }
163     auto save_errno = errno;
164     errno = 0;
165     auto has_shared_blocks = fs_mgr_has_shared_blocks(entry->mount_point, entry->blk_device);
166     if (!has_shared_blocks && (entry->mount_point == "/system")) {
167         has_shared_blocks = fs_mgr_has_shared_blocks("/", entry->blk_device);
168     }
169     // special case for first stage init for system as root (taimen)
170     if (!has_shared_blocks && (errno == ENOENT) && (entry->blk_device == "/dev/root")) {
171         has_shared_blocks = true;
172     }
173     errno = save_errno;
174     return has_shared_blocks;
175 }
176 
fs_mgr_rm_all(const std::string & path,bool * change=nullptr,int level=0)177 bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
178     auto save_errno = errno;
179     std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
180     if (!dir) {
181         if (errno == ENOENT) {
182             errno = save_errno;
183             return true;
184         }
185         PERROR << "opendir " << path << " depth=" << level;
186         if ((errno == EPERM) && (level != 0)) {
187             errno = save_errno;
188             return true;
189         }
190         return false;
191     }
192     dirent* entry;
193     auto ret = true;
194     while ((entry = readdir(dir.get()))) {
195         if (("."s == entry->d_name) || (".."s == entry->d_name)) continue;
196         auto file = path + "/" + entry->d_name;
197         if (entry->d_type == DT_UNKNOWN) {
198             struct stat st;
199             save_errno = errno;
200             if (!lstat(file.c_str(), &st) && (st.st_mode & S_IFDIR)) entry->d_type = DT_DIR;
201             errno = save_errno;
202         }
203         if (entry->d_type == DT_DIR) {
204             ret &= fs_mgr_rm_all(file, change, level + 1);
205             if (!rmdir(file.c_str())) {
206                 if (change) *change = true;
207             } else {
208                 if (errno != ENOENT) ret = false;
209                 PERROR << "rmdir " << file << " depth=" << level;
210             }
211             continue;
212         }
213         if (!unlink(file.c_str())) {
214             if (change) *change = true;
215         } else {
216             if (errno != ENOENT) ret = false;
217             PERROR << "rm " << file << " depth=" << level;
218         }
219     }
220     return ret;
221 }
222 
223 const auto kUpperName = "upper"s;
224 const auto kWorkName = "work"s;
225 const auto kOverlayTopDir = "/overlay"s;
226 
fs_mgr_get_overlayfs_candidate(const std::string & mount_point)227 std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) {
228     if (!fs_mgr_is_dir(mount_point)) return "";
229     const auto base = android::base::Basename(mount_point) + "/";
230     for (const auto& overlay_mount_point : kOverlayMountPoints) {
231         auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
232         auto upper = dir + kUpperName;
233         if (!fs_mgr_is_dir(upper)) continue;
234         auto work = dir + kWorkName;
235         if (!fs_mgr_is_dir(work)) continue;
236         if (!fs_mgr_dir_is_writable(work)) continue;
237         return dir;
238     }
239     return "";
240 }
241 
242 const auto kLowerdirOption = "lowerdir="s;
243 const auto kUpperdirOption = "upperdir="s;
244 
245 // default options for mount_point, returns empty string for none available.
fs_mgr_get_overlayfs_options(const std::string & mount_point)246 std::string fs_mgr_get_overlayfs_options(const std::string& mount_point) {
247     auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
248     if (candidate.empty()) return "";
249     auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName +
250                ",workdir=" + candidate + kWorkName;
251     if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
252         ret += ",override_creds=off";
253     }
254     return ret;
255 }
256 
fs_mgr_mount_point(const std::string & mount_point)257 const std::string fs_mgr_mount_point(const std::string& mount_point) {
258     if ("/"s != mount_point) return mount_point;
259     return "/system";
260 }
261 
fs_mgr_rw_access(const std::string & path)262 bool fs_mgr_rw_access(const std::string& path) {
263     if (path.empty()) return false;
264     auto save_errno = errno;
265     auto ret = access(path.c_str(), R_OK | W_OK) == 0;
266     errno = save_errno;
267     return ret;
268 }
269 
fs_mgr_overlayfs_already_mounted(const std::string & mount_point,bool overlay_only=true)270 bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true) {
271     Fstab fstab;
272     auto save_errno = errno;
273     if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
274         return false;
275     }
276     errno = save_errno;
277     const auto lowerdir = kLowerdirOption + mount_point;
278     for (const auto& entry : fstab) {
279         if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
280         if (mount_point != entry.mount_point) continue;
281         if (!overlay_only) return true;
282         const auto options = android::base::Split(entry.fs_options, ",");
283         for (const auto& opt : options) {
284             if (opt == lowerdir) {
285                 return true;
286             }
287         }
288     }
289     return false;
290 }
291 
fs_mgr_wants_overlayfs(FstabEntry * entry)292 bool fs_mgr_wants_overlayfs(FstabEntry* entry) {
293     // Don't check entries that are managed by vold.
294     if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false;
295 
296     // *_other doesn't want overlayfs.
297     if (entry->fs_mgr_flags.slot_select_other) return false;
298 
299     // Only concerned with readonly partitions.
300     if (!(entry->flags & MS_RDONLY)) return false;
301 
302     // If unbindable, do not allow overlayfs as this could expose us to
303     // security issues.  On Android, this could also be used to turn off
304     // the ability to overlay an otherwise acceptable filesystem since
305     // /system and /vendor are never bound(sic) to.
306     if (entry->flags & MS_UNBINDABLE) return false;
307 
308     if (!fs_mgr_overlayfs_enabled(entry)) return false;
309 
310     return true;
311 }
312 constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
313 
fs_mgr_overlayfs_setup_dir(const std::string & dir,std::string * overlay,bool * change)314 bool fs_mgr_overlayfs_setup_dir(const std::string& dir, std::string* overlay, bool* change) {
315     auto ret = true;
316     auto top = dir + kOverlayTopDir;
317     if (setfscreatecon(kOverlayfsFileContext)) {
318         ret = false;
319         PERROR << "setfscreatecon " << kOverlayfsFileContext;
320     }
321     auto save_errno = errno;
322     if (!mkdir(top.c_str(), 0755)) {
323         if (change) *change = true;
324     } else if (errno != EEXIST) {
325         ret = false;
326         PERROR << "mkdir " << top;
327     } else {
328         errno = save_errno;
329     }
330     setfscreatecon(nullptr);
331 
332     if (overlay) *overlay = std::move(top);
333     return ret;
334 }
335 
fs_mgr_overlayfs_setup_one(const std::string & overlay,const std::string & mount_point,bool * change)336 bool fs_mgr_overlayfs_setup_one(const std::string& overlay, const std::string& mount_point,
337                                 bool* change) {
338     auto ret = true;
339     if (fs_mgr_overlayfs_already_mounted(mount_point)) return ret;
340     auto fsrec_mount_point = overlay + "/" + android::base::Basename(mount_point) + "/";
341 
342     if (setfscreatecon(kOverlayfsFileContext)) {
343         ret = false;
344         PERROR << "setfscreatecon " << kOverlayfsFileContext;
345     }
346     auto save_errno = errno;
347     if (!mkdir(fsrec_mount_point.c_str(), 0755)) {
348         if (change) *change = true;
349     } else if (errno != EEXIST) {
350         ret = false;
351         PERROR << "mkdir " << fsrec_mount_point;
352     } else {
353         errno = save_errno;
354     }
355 
356     save_errno = errno;
357     if (!mkdir((fsrec_mount_point + kWorkName).c_str(), 0755)) {
358         if (change) *change = true;
359     } else if (errno != EEXIST) {
360         ret = false;
361         PERROR << "mkdir " << fsrec_mount_point << kWorkName;
362     } else {
363         errno = save_errno;
364     }
365     setfscreatecon(nullptr);
366 
367     auto new_context = fs_mgr_get_context(mount_point);
368     if (!new_context.empty() && setfscreatecon(new_context.c_str())) {
369         ret = false;
370         PERROR << "setfscreatecon " << new_context;
371     }
372     auto upper = fsrec_mount_point + kUpperName;
373     save_errno = errno;
374     if (!mkdir(upper.c_str(), 0755)) {
375         if (change) *change = true;
376     } else if (errno != EEXIST) {
377         ret = false;
378         PERROR << "mkdir " << upper;
379     } else {
380         errno = save_errno;
381     }
382     if (!new_context.empty()) setfscreatecon(nullptr);
383 
384     return ret;
385 }
386 
fs_mgr_overlayfs_slot_number()387 uint32_t fs_mgr_overlayfs_slot_number() {
388     return SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
389 }
390 
391 const auto kPhysicalDevice = "/dev/block/by-name/"s;
392 
fs_mgr_overlayfs_super_device(uint32_t slot_number)393 std::string fs_mgr_overlayfs_super_device(uint32_t slot_number) {
394     return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number);
395 }
396 
fs_mgr_overlayfs_has_logical(const Fstab & fstab)397 bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) {
398     for (const auto& entry : fstab) {
399         if (entry.fs_mgr_flags.logical) {
400             return true;
401         }
402     }
403     return false;
404 }
405 
fs_mgr_overlayfs_umount_scratch()406 void fs_mgr_overlayfs_umount_scratch() {
407     // Lazy umount will allow us to move on and possibly later
408     // establish a new fresh mount without requiring a reboot should
409     // the developer wish to restart.  Old references should melt
410     // away or have no data.  Main goal is to shut the door on the
411     // current overrides with an expectation of a subsequent reboot,
412     // thus any errors here are ignored.
413     umount2(kScratchMountPoint.c_str(), MNT_DETACH);
414     LINFO << "umount(" << kScratchMountPoint << ")";
415     rmdir(kScratchMountPoint.c_str());
416 }
417 
418 // reduce 'DM_DEV_STATUS failed for scratch: No such device or address' noise
419 std::string scratch_device_cache;
420 
fs_mgr_overlayfs_teardown_scratch(const std::string & overlay,bool * change)421 bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) {
422     // umount and delete kScratchMountPoint storage if we have logical partitions
423     if (overlay != kScratchMountPoint) return true;
424     scratch_device_cache.erase();
425     auto slot_number = fs_mgr_overlayfs_slot_number();
426     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
427     if (!fs_mgr_rw_access(super_device)) return true;
428 
429     auto save_errno = errno;
430     if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
431         fs_mgr_overlayfs_umount_scratch();
432     }
433     auto builder = MetadataBuilder::New(super_device, slot_number);
434     if (!builder) {
435         errno = save_errno;
436         return true;
437     }
438     const auto partition_name = android::base::Basename(kScratchMountPoint);
439     if (builder->FindPartition(partition_name) == nullptr) {
440         errno = save_errno;
441         return true;
442     }
443     builder->RemovePartition(partition_name);
444     auto metadata = builder->Export();
445     if (metadata && UpdatePartitionTable(super_device, *metadata.get(), slot_number)) {
446         if (change) *change = true;
447         if (!DestroyLogicalPartition(partition_name, 0s)) return false;
448     } else {
449         LERROR << "delete partition " << overlay;
450         return false;
451     }
452     errno = save_errno;
453     return true;
454 }
455 
fs_mgr_overlayfs_teardown_one(const std::string & overlay,const std::string & mount_point,bool * change)456 bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
457                                    bool* change) {
458     const auto top = overlay + kOverlayTopDir;
459 
460     if (!fs_mgr_access(top)) return fs_mgr_overlayfs_teardown_scratch(overlay, change);
461 
462     auto cleanup_all = mount_point.empty();
463     const auto partition_name = android::base::Basename(mount_point);
464     const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
465     const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir.substr(1) + ".teardown"
466                                      : top + "/." + partition_name + ".teardown";
467     auto ret = fs_mgr_rm_all(newpath);
468     auto save_errno = errno;
469     if (!rename(oldpath.c_str(), newpath.c_str())) {
470         if (change) *change = true;
471     } else if (errno != ENOENT) {
472         ret = false;
473         PERROR << "mv " << oldpath << " " << newpath;
474     } else {
475         errno = save_errno;
476     }
477     ret &= fs_mgr_rm_all(newpath, change);
478     save_errno = errno;
479     if (!rmdir(newpath.c_str())) {
480         if (change) *change = true;
481     } else if (errno != ENOENT) {
482         ret = false;
483         PERROR << "rmdir " << newpath;
484     } else {
485         errno = save_errno;
486     }
487     if (!cleanup_all) {
488         save_errno = errno;
489         if (!rmdir(top.c_str())) {
490             if (change) *change = true;
491             cleanup_all = true;
492         } else if (errno == ENOTEMPTY) {
493             cleanup_all = true;
494             // cleanup all if the content is all hidden (leading .)
495             std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(top.c_str()), closedir);
496             if (!dir) {
497                 PERROR << "opendir " << top;
498             } else {
499                 dirent* entry;
500                 while ((entry = readdir(dir.get()))) {
501                     if (entry->d_name[0] != '.') {
502                         cleanup_all = false;
503                         break;
504                     }
505                 }
506             }
507             errno = save_errno;
508         } else if (errno == ENOENT) {
509             cleanup_all = true;
510             errno = save_errno;
511         } else {
512             ret = false;
513             PERROR << "rmdir " << top;
514         }
515     }
516     if (cleanup_all) ret &= fs_mgr_overlayfs_teardown_scratch(overlay, change);
517     return ret;
518 }
519 
fs_mgr_overlayfs_mount(const std::string & mount_point)520 bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
521     auto options = fs_mgr_get_overlayfs_options(mount_point);
522     if (options.empty()) return false;
523 
524     // hijack __mount() report format to help triage
525     auto report = "__mount(source=overlay,target="s + mount_point + ",type=overlay";
526     const auto opt_list = android::base::Split(options, ",");
527     for (const auto& opt : opt_list) {
528         if (android::base::StartsWith(opt, kUpperdirOption)) {
529             report = report + "," + opt;
530             break;
531         }
532     }
533     report = report + ")=";
534 
535     auto ret = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_RELATIME,
536                      options.c_str());
537     if (ret) {
538         PERROR << report << ret;
539         return false;
540     } else {
541         LINFO << report << ret;
542         return true;
543     }
544 }
545 
546 // Mount kScratchMountPoint
fs_mgr_overlayfs_mount_scratch(const std::string & device_path,const std::string mnt_type,bool readonly=false)547 bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::string mnt_type,
548                                     bool readonly = false) {
549     if (readonly) {
550         if (!fs_mgr_access(device_path)) return false;
551     } else {
552         if (!fs_mgr_rw_access(device_path)) return false;
553     }
554 
555     auto f2fs = fs_mgr_is_f2fs(device_path);
556     auto ext4 = fs_mgr_is_ext4(device_path);
557     if (!f2fs && !ext4) return false;
558 
559     if (setfscreatecon(kOverlayfsFileContext)) {
560         PERROR << "setfscreatecon " << kOverlayfsFileContext;
561     }
562     if (mkdir(kScratchMountPoint.c_str(), 0755) && (errno != EEXIST)) {
563         PERROR << "create " << kScratchMountPoint;
564     }
565 
566     FstabEntry entry;
567     entry.blk_device = device_path;
568     entry.mount_point = kScratchMountPoint;
569     entry.fs_type = mnt_type;
570     if ((mnt_type == "f2fs") && !f2fs) entry.fs_type = "ext4";
571     if ((mnt_type == "ext4") && !ext4) entry.fs_type = "f2fs";
572     entry.flags = MS_RELATIME;
573     if (readonly) {
574         entry.flags |= MS_RDONLY;
575     } else {
576         fs_mgr_set_blk_ro(device_path, false);
577     }
578     auto save_errno = errno;
579     auto mounted = fs_mgr_do_mount_one(entry) == 0;
580     if (!mounted) {
581         if ((entry.fs_type == "f2fs") && ext4) {
582             entry.fs_type = "ext4";
583             mounted = fs_mgr_do_mount_one(entry) == 0;
584         } else if ((entry.fs_type == "ext4") && f2fs) {
585             entry.fs_type = "f2fs";
586             mounted = fs_mgr_do_mount_one(entry) == 0;
587         }
588         if (!mounted) save_errno = errno;
589     }
590     setfscreatecon(nullptr);
591     if (!mounted) rmdir(kScratchMountPoint.c_str());
592     errno = save_errno;
593     return mounted;
594 }
595 
596 const std::string kMkF2fs("/system/bin/make_f2fs");
597 const std::string kMkExt4("/system/bin/mke2fs");
598 
599 // Only a suggestion for _first_ try during mounting
fs_mgr_overlayfs_scratch_mount_type()600 std::string fs_mgr_overlayfs_scratch_mount_type() {
601     if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("f2fs")) {
602         return "f2fs";
603     }
604     if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("ext4")) {
605         return "ext4";
606     }
607     return "auto";
608 }
609 
fs_mgr_overlayfs_scratch_device()610 std::string fs_mgr_overlayfs_scratch_device() {
611     if (!scratch_device_cache.empty()) return scratch_device_cache;
612 
613     // Is this a multiple super device (retrofit)?
614     auto slot_number = fs_mgr_overlayfs_slot_number();
615     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
616     auto path = fs_mgr_overlayfs_super_device(slot_number == 0);
617     if (super_device == path) {
618         // Create from within single super device;
619         auto& dm = DeviceMapper::Instance();
620         const auto partition_name = android::base::Basename(kScratchMountPoint);
621         if (!dm.GetDmDevicePathByName(partition_name, &path)) {
622             // non-DAP A/B device?
623             if (fs_mgr_access(super_device)) return "";
624             auto other_slot = fs_mgr_get_other_slot_suffix();
625             if (other_slot.empty()) return "";
626             path = kPhysicalDevice + "system" + other_slot;
627         }
628     }
629     return scratch_device_cache = path;
630 }
631 
fs_mgr_overlayfs_make_scratch(const std::string & scratch_device,const std::string & mnt_type)632 bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std::string& mnt_type) {
633     // Force mkfs by design for overlay support of adb remount, simplify and
634     // thus do not rely on fsck to correct problems that could creep in.
635     auto command = ""s;
636     if (mnt_type == "f2fs") {
637         command = kMkF2fs + " -w 4096 -f -d1 -l" + android::base::Basename(kScratchMountPoint);
638     } else if (mnt_type == "ext4") {
639         command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
640     } else {
641         errno = ESRCH;
642         LERROR << mnt_type << " has no mkfs cookbook";
643         return false;
644     }
645     command += " " + scratch_device + " >/dev/null 2>/dev/null </dev/null";
646     fs_mgr_set_blk_ro(scratch_device, false);
647     auto ret = system(command.c_str());
648     if (ret) {
649         LERROR << "make " << mnt_type << " filesystem on " << scratch_device << " return=" << ret;
650         return false;
651     }
652     return true;
653 }
654 
fs_mgr_overlayfs_create_scratch(const Fstab & fstab,std::string * scratch_device,bool * partition_exists,bool * change)655 bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device,
656                                      bool* partition_exists, bool* change) {
657     *scratch_device = fs_mgr_overlayfs_scratch_device();
658     *partition_exists = fs_mgr_rw_access(*scratch_device);
659     auto partition_create = !*partition_exists;
660     // Do we need to create a logical "scratch" partition?
661     if (!partition_create && android::base::StartsWith(*scratch_device, kPhysicalDevice)) {
662         return true;
663     }
664     auto slot_number = fs_mgr_overlayfs_slot_number();
665     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
666     if (!fs_mgr_rw_access(super_device)) return false;
667     if (!fs_mgr_overlayfs_has_logical(fstab)) return false;
668     auto builder = MetadataBuilder::New(super_device, slot_number);
669     if (!builder) {
670         LERROR << "open " << super_device << " metadata";
671         return false;
672     }
673     const auto partition_name = android::base::Basename(kScratchMountPoint);
674     auto partition = builder->FindPartition(partition_name);
675     *partition_exists = partition != nullptr;
676     auto changed = false;
677     if (!*partition_exists) {
678         partition = builder->AddPartition(partition_name, LP_PARTITION_ATTR_NONE);
679         if (!partition) {
680             LERROR << "create " << partition_name;
681             return false;
682         }
683         changed = true;
684     }
685     // Take half of free space, minimum 512MB or maximum free - margin.
686     static constexpr auto kMinimumSize = uint64_t(512 * 1024 * 1024);
687     if (partition->size() < kMinimumSize) {
688         auto partition_size =
689                 builder->AllocatableSpace() - builder->UsedSpace() + partition->size();
690         if ((partition_size > kMinimumSize) || !partition->size()) {
691             // Leave some space for free space jitter of a few erase
692             // blocks, in case they are needed for any individual updates
693             // to any other partition that needs to be flashed while
694             // overlayfs is in force.  Of course if margin_size is not
695             // enough could normally get a flash failure, so
696             // ResizePartition() will delete the scratch partition in
697             // order to fulfill.  Deleting scratch will destroy all of
698             // the adb remount overrides :-( .
699             auto margin_size = uint64_t(3 * 256 * 1024);
700             BlockDeviceInfo info;
701             if (builder->GetBlockDeviceInfo(partition_name, &info)) {
702                 margin_size = 3 * info.logical_block_size;
703             }
704             partition_size = std::max(std::min(kMinimumSize, partition_size - margin_size),
705                                       partition_size / 2);
706             if (partition_size > partition->size()) {
707                 if (!builder->ResizePartition(partition, partition_size)) {
708                     LERROR << "resize " << partition_name;
709                     return false;
710                 }
711                 if (!partition_create) DestroyLogicalPartition(partition_name, 10s);
712                 changed = true;
713                 *partition_exists = false;
714             }
715         }
716     }
717     // land the update back on to the partition
718     if (changed) {
719         auto metadata = builder->Export();
720         if (!metadata || !UpdatePartitionTable(super_device, *metadata.get(), slot_number)) {
721             LERROR << "add partition " << partition_name;
722             return false;
723         }
724 
725         if (change) *change = true;
726     }
727 
728     if (changed || partition_create) {
729         if (!CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s,
730                                     scratch_device))
731             return false;
732 
733         if (change) *change = true;
734     }
735     return true;
736 }
737 
738 // Create and mount kScratchMountPoint storage if we have logical partitions
fs_mgr_overlayfs_setup_scratch(const Fstab & fstab,bool * change)739 bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab, bool* change) {
740     if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
741 
742     std::string scratch_device;
743     bool partition_exists;
744     if (!fs_mgr_overlayfs_create_scratch(fstab, &scratch_device, &partition_exists, change)) {
745         return false;
746     }
747 
748     // If the partition exists, assume first that it can be mounted.
749     auto mnt_type = fs_mgr_overlayfs_scratch_mount_type();
750     if (partition_exists) {
751         if (fs_mgr_overlayfs_mount_scratch(scratch_device, mnt_type)) {
752             if (!fs_mgr_access(kScratchMountPoint + kOverlayTopDir) &&
753                 !fs_mgr_filesystem_has_space(kScratchMountPoint)) {
754                 // declare it useless, no overrides and no free space
755                 fs_mgr_overlayfs_umount_scratch();
756             } else {
757                 if (change) *change = true;
758                 return true;
759             }
760         }
761         // partition existed, but was not initialized; fall through to make it.
762         errno = 0;
763     }
764 
765     if (!fs_mgr_overlayfs_make_scratch(scratch_device, mnt_type)) return false;
766 
767     if (change) *change = true;
768 
769     return fs_mgr_overlayfs_mount_scratch(scratch_device, mnt_type);
770 }
771 
fs_mgr_overlayfs_scratch_can_be_mounted(const std::string & scratch_device)772 bool fs_mgr_overlayfs_scratch_can_be_mounted(const std::string& scratch_device) {
773     if (scratch_device.empty()) return false;
774     if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return false;
775     if (android::base::StartsWith(scratch_device, kPhysicalDevice)) return true;
776     if (fs_mgr_rw_access(scratch_device)) return true;
777     auto slot_number = fs_mgr_overlayfs_slot_number();
778     auto super_device = fs_mgr_overlayfs_super_device(slot_number);
779     if (!fs_mgr_rw_access(super_device)) return false;
780     auto builder = MetadataBuilder::New(super_device, slot_number);
781     if (!builder) return false;
782     return builder->FindPartition(android::base::Basename(kScratchMountPoint)) != nullptr;
783 }
784 
fs_mgr_overlayfs_invalid()785 bool fs_mgr_overlayfs_invalid() {
786     if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true;
787 
788     // in recovery, fastbootd, or gsi mode, not allowed!
789     if (fs_mgr_access("/system/bin/recovery")) return true;
790     auto save_errno = errno;
791     auto ret = android::gsi::IsGsiRunning();
792     errno = save_errno;
793     return ret;
794 }
795 
796 }  // namespace
797 
fs_mgr_overlayfs_candidate_list(const Fstab & fstab)798 Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) {
799     Fstab candidates;
800     for (const auto& entry : fstab) {
801         FstabEntry new_entry = entry;
802         if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) &&
803             !fs_mgr_wants_overlayfs(&new_entry)) {
804             continue;
805         }
806         auto new_mount_point = fs_mgr_mount_point(entry.mount_point);
807         auto duplicate_or_more_specific = false;
808         for (auto it = candidates.begin(); it != candidates.end();) {
809             auto it_mount_point = fs_mgr_mount_point(it->mount_point);
810             if ((it_mount_point == new_mount_point) ||
811                 (android::base::StartsWith(new_mount_point, it_mount_point + "/"))) {
812                 duplicate_or_more_specific = true;
813                 break;
814             }
815             if (android::base::StartsWith(it_mount_point, new_mount_point + "/")) {
816                 it = candidates.erase(it);
817             } else {
818                 ++it;
819             }
820         }
821         if (!duplicate_or_more_specific) candidates.emplace_back(std::move(new_entry));
822     }
823     return candidates;
824 }
825 
fs_mgr_overlayfs_mount_all(Fstab * fstab)826 bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
827     auto ret = false;
828     if (fs_mgr_overlayfs_invalid()) return ret;
829 
830     auto scratch_can_be_mounted = true;
831     for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) {
832         if (fs_mgr_is_verity_enabled(entry)) continue;
833         auto mount_point = fs_mgr_mount_point(entry.mount_point);
834         if (fs_mgr_overlayfs_already_mounted(mount_point)) {
835             ret = true;
836             continue;
837         }
838         if (scratch_can_be_mounted) {
839             scratch_can_be_mounted = false;
840             auto scratch_device = fs_mgr_overlayfs_scratch_device();
841             if (fs_mgr_overlayfs_scratch_can_be_mounted(scratch_device) &&
842                 fs_mgr_wait_for_file(scratch_device, 10s)) {
843                 const auto mount_type = fs_mgr_overlayfs_scratch_mount_type();
844                 if (fs_mgr_overlayfs_mount_scratch(scratch_device, mount_type,
845                                                    true /* readonly */)) {
846                     auto has_overlayfs_dir = fs_mgr_access(kScratchMountPoint + kOverlayTopDir);
847                     fs_mgr_overlayfs_umount_scratch();
848                     if (has_overlayfs_dir) {
849                         fs_mgr_overlayfs_mount_scratch(scratch_device, mount_type);
850                     }
851                 }
852             }
853         }
854         if (fs_mgr_overlayfs_mount(mount_point)) ret = true;
855     }
856     return ret;
857 }
858 
fs_mgr_overlayfs_required_devices(Fstab * fstab)859 std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab) {
860     if (fs_mgr_overlayfs_invalid()) return {};
861 
862     if (GetEntryForMountPoint(fstab, kScratchMountPoint) != nullptr) {
863         return {};
864     }
865 
866     for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) {
867         if (fs_mgr_is_verity_enabled(entry)) continue;
868         if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) continue;
869         auto device = fs_mgr_overlayfs_scratch_device();
870         if (!fs_mgr_overlayfs_scratch_can_be_mounted(device)) break;
871         return {device};
872     }
873     return {};
874 }
875 
876 // Returns false if setup not permitted, errno set to last error.
877 // If something is altered, set *change.
fs_mgr_overlayfs_setup(const char * backing,const char * mount_point,bool * change,bool force)878 bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* change,
879                             bool force) {
880     if (change) *change = false;
881     auto ret = false;
882     if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return ret;
883     if (!fs_mgr_boot_completed()) {
884         errno = EBUSY;
885         PERROR << "setup";
886         return ret;
887     }
888 
889     auto save_errno = errno;
890     Fstab fstab;
891     if (!ReadDefaultFstab(&fstab)) {
892         return false;
893     }
894     errno = save_errno;
895     auto candidates = fs_mgr_overlayfs_candidate_list(fstab);
896     for (auto it = candidates.begin(); it != candidates.end();) {
897         if (mount_point &&
898             (fs_mgr_mount_point(it->mount_point) != fs_mgr_mount_point(mount_point))) {
899             it = candidates.erase(it);
900             continue;
901         }
902         save_errno = errno;
903         auto verity_enabled = !force && fs_mgr_is_verity_enabled(*it);
904         if (errno == ENOENT || errno == ENXIO) errno = save_errno;
905         if (verity_enabled) {
906             it = candidates.erase(it);
907             continue;
908         }
909         ++it;
910     }
911 
912     if (candidates.empty()) return ret;
913 
914     std::string dir;
915     for (const auto& overlay_mount_point : kOverlayMountPoints) {
916         if (backing && backing[0] && (overlay_mount_point != backing)) continue;
917         if (overlay_mount_point == kScratchMountPoint) {
918             if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue;
919         } else {
920             if (GetEntryForMountPoint(&fstab, overlay_mount_point) == nullptr) {
921                 continue;
922             }
923         }
924         dir = overlay_mount_point;
925         break;
926     }
927     if (dir.empty()) {
928         if (change && *change) errno = ESRCH;
929         if (errno == EPERM) errno = save_errno;
930         return ret;
931     }
932 
933     std::string overlay;
934     ret |= fs_mgr_overlayfs_setup_dir(dir, &overlay, change);
935     for (const auto& entry : candidates) {
936         ret |= fs_mgr_overlayfs_setup_one(overlay, fs_mgr_mount_point(entry.mount_point), change);
937     }
938     return ret;
939 }
940 
941 // Returns false if teardown not permitted, errno set to last error.
942 // If something is altered, set *change.
fs_mgr_overlayfs_teardown(const char * mount_point,bool * change)943 bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
944     if (change) *change = false;
945     auto ret = true;
946     // If scratch exists, but is not mounted, lets gain access to clean
947     // specific override entries.
948     auto mount_scratch = false;
949     if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
950         auto scratch_device = fs_mgr_overlayfs_scratch_device();
951         if (scratch_device.empty()) {
952             auto slot_number = fs_mgr_overlayfs_slot_number();
953             auto super_device = fs_mgr_overlayfs_super_device(slot_number);
954             const auto partition_name = android::base::Basename(kScratchMountPoint);
955             CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s,
956                                    &scratch_device);
957         }
958         mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device,
959                                                        fs_mgr_overlayfs_scratch_mount_type());
960     }
961     for (const auto& overlay_mount_point : kOverlayMountPoints) {
962         ret &= fs_mgr_overlayfs_teardown_one(
963                 overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change);
964     }
965     if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
966         // After obligatory teardown to make sure everything is clean, but if
967         // we didn't want overlayfs in the the first place, we do not want to
968         // waste time on a reboot (or reboot request message).
969         if (change) *change = false;
970     }
971     // And now that we did what we could, lets inform
972     // caller that there may still be more to do.
973     if (!fs_mgr_boot_completed()) {
974         errno = EBUSY;
975         PERROR << "teardown";
976         ret = false;
977     }
978     if (mount_scratch) fs_mgr_overlayfs_umount_scratch();
979 
980     return ret;
981 }
982 
fs_mgr_overlayfs_is_setup()983 bool fs_mgr_overlayfs_is_setup() {
984     if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
985     Fstab fstab;
986     if (!ReadDefaultFstab(&fstab)) {
987         return false;
988     }
989     if (fs_mgr_overlayfs_invalid()) return false;
990     for (const auto& entry : fs_mgr_overlayfs_candidate_list(fstab)) {
991         if (fs_mgr_is_verity_enabled(entry)) continue;
992         if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) return true;
993     }
994     return false;
995 }
996 
997 #endif  // ALLOW_ADBD_DISABLE_VERITY != 0
998 
fs_mgr_has_shared_blocks(const std::string & mount_point,const std::string & dev)999 bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) {
1000     struct statfs fs;
1001     if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) ||
1002         (fs.f_type != EXT4_SUPER_MAGIC)) {
1003         return false;
1004     }
1005 
1006     android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
1007     if (fd < 0) return false;
1008 
1009     struct ext4_super_block sb;
1010     if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) ||
1011         (TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) {
1012         return false;
1013     }
1014 
1015     struct fs_info info;
1016     if (ext4_parse_sb(&sb, &info) < 0) return false;
1017 
1018     return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0;
1019 }
1020 
fs_mgr_get_context(const std::string & mount_point)1021 std::string fs_mgr_get_context(const std::string& mount_point) {
1022     char* ctx = nullptr;
1023     if (getfilecon(mount_point.c_str(), &ctx) == -1) {
1024         return "";
1025     }
1026 
1027     std::string context(ctx);
1028     free(ctx);
1029     return context;
1030 }
1031 
fs_mgr_overlayfs_valid()1032 OverlayfsValidResult fs_mgr_overlayfs_valid() {
1033     // Overlayfs available in the kernel, and patched for override_creds?
1034     if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) {
1035         return OverlayfsValidResult::kOverrideCredsRequired;
1036     }
1037     if (!fs_mgr_overlayfs_filesystem_available("overlay")) {
1038         return OverlayfsValidResult::kNotSupported;
1039     }
1040     struct utsname uts;
1041     if (uname(&uts) == -1) {
1042         return OverlayfsValidResult::kNotSupported;
1043     }
1044     int major, minor;
1045     if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
1046         return OverlayfsValidResult::kNotSupported;
1047     }
1048     if (major < 4) {
1049         return OverlayfsValidResult::kOk;
1050     }
1051     if (major > 4) {
1052         return OverlayfsValidResult::kNotSupported;
1053     }
1054     if (minor > 3) {
1055         return OverlayfsValidResult::kNotSupported;
1056     }
1057     return OverlayfsValidResult::kOk;
1058 }
1059