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