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