1 /*
2  * Copyright (C) 2017 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 "first_stage_mount.h"
18 
19 #include <stdlib.h>
20 #include <sys/mount.h>
21 #include <unistd.h>
22 
23 #include <chrono>
24 #include <filesystem>
25 #include <map>
26 #include <memory>
27 #include <set>
28 #include <string>
29 #include <vector>
30 
31 #include <android-base/chrono_utils.h>
32 #include <android-base/file.h>
33 #include <android-base/logging.h>
34 #include <android-base/stringprintf.h>
35 #include <android-base/strings.h>
36 #include <fs_avb/fs_avb.h>
37 #include <fs_mgr.h>
38 #include <fs_mgr_dm_linear.h>
39 #include <fs_mgr_overlayfs.h>
40 #include <libfiemap/image_manager.h>
41 #include <libgsi/libgsi.h>
42 #include <liblp/liblp.h>
43 #include <libsnapshot/snapshot.h>
44 
45 #include "block_dev_initializer.h"
46 #include "devices.h"
47 #include "result.h"
48 #include "snapuserd_transition.h"
49 #include "switch_root.h"
50 #include "uevent.h"
51 #include "uevent_listener.h"
52 #include "util.h"
53 
54 using android::base::ReadFileToString;
55 using android::base::Result;
56 using android::base::Split;
57 using android::base::StringPrintf;
58 using android::base::Timer;
59 using android::fiemap::IImageManager;
60 using android::fs_mgr::AvbHandle;
61 using android::fs_mgr::AvbHandleStatus;
62 using android::fs_mgr::AvbHashtreeResult;
63 using android::fs_mgr::AvbUniquePtr;
64 using android::fs_mgr::Fstab;
65 using android::fs_mgr::FstabEntry;
66 using android::fs_mgr::ReadDefaultFstab;
67 using android::fs_mgr::ReadFstabFromDt;
68 using android::fs_mgr::SkipMountingPartitions;
69 using android::fs_mgr::TransformFstabForDsu;
70 using android::snapshot::SnapshotManager;
71 
72 using namespace std::literals;
73 
74 namespace android {
75 namespace init {
76 
77 // Class Declarations
78 // ------------------
79 class FirstStageMount {
80   public:
81     FirstStageMount(Fstab fstab);
82     virtual ~FirstStageMount() = default;
83 
84     // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
85     // based on device tree configurations.
86     static Result<std::unique_ptr<FirstStageMount>> Create();
87     bool DoCreateDevices();    // Creates devices and logical partitions from storage devices
88     bool DoFirstStageMount();  // Mounts fstab entries read from device tree.
89     bool InitDevices();
90 
91   protected:
92     bool InitRequiredDevices(std::set<std::string> devices);
93     bool CreateLogicalPartitions();
94     bool CreateSnapshotPartitions(android::snapshot::SnapshotManager* sm);
95     bool MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
96                         Fstab::iterator* end = nullptr);
97 
98     bool MountPartitions();
99     bool TrySwitchSystemAsRoot();
100     bool IsDmLinearEnabled();
101     void GetSuperDeviceName(std::set<std::string>* devices);
102     bool InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata);
103     void UseDsuIfPresent();
104     // Reads all fstab.avb_keys from the ramdisk for first-stage mount.
105     void PreloadAvbKeys();
106     // Copies /avb/*.avbpubkey used for DSU from the ramdisk to /metadata for key
107     // revocation check by DSU installation service.
108     void CopyDsuAvbKeys();
109 
110     // Pure virtual functions.
111     virtual bool GetDmVerityDevices(std::set<std::string>* devices) = 0;
112     virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0;
113 
114     bool need_dm_verity_;
115     bool dsu_not_on_userdata_ = false;
116     bool use_snapuserd_ = false;
117 
118     Fstab fstab_;
119     // The super path is only set after InitDevices, and is invalid before.
120     std::string super_path_;
121     std::string super_partition_name_;
122     BlockDevInitializer block_dev_init_;
123     // Reads all AVB keys before chroot into /system, as they might be used
124     // later when mounting other partitions, e.g., /vendor and /product.
125     std::map<std::string, std::vector<std::string>> preload_avb_key_blobs_;
126 };
127 
128 class FirstStageMountVBootV1 : public FirstStageMount {
129   public:
FirstStageMountVBootV1(Fstab fstab)130     FirstStageMountVBootV1(Fstab fstab) : FirstStageMount(std::move(fstab)) {}
131     ~FirstStageMountVBootV1() override = default;
132 
133   protected:
134     bool GetDmVerityDevices(std::set<std::string>* devices) override;
135     bool SetUpDmVerity(FstabEntry* fstab_entry) override;
136 };
137 
138 class FirstStageMountVBootV2 : public FirstStageMount {
139   public:
140     friend void SetInitAvbVersionInRecovery();
141 
142     FirstStageMountVBootV2(Fstab fstab);
143     ~FirstStageMountVBootV2() override = default;
144 
145   protected:
146     bool GetDmVerityDevices(std::set<std::string>* devices) override;
147     bool SetUpDmVerity(FstabEntry* fstab_entry) override;
148     bool InitAvbHandle();
149 
150     std::vector<std::string> vbmeta_partitions_;
151     AvbUniquePtr avb_handle_;
152 };
153 
154 // Static Functions
155 // ----------------
IsDtVbmetaCompatible(const Fstab & fstab)156 static inline bool IsDtVbmetaCompatible(const Fstab& fstab) {
157     if (std::any_of(fstab.begin(), fstab.end(),
158                     [](const auto& entry) { return entry.fs_mgr_flags.avb; })) {
159         return true;
160     }
161     return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
162 }
163 
ReadFirstStageFstab()164 static Result<Fstab> ReadFirstStageFstab() {
165     Fstab fstab;
166     if (!ReadFstabFromDt(&fstab)) {
167         if (ReadDefaultFstab(&fstab)) {
168             fstab.erase(std::remove_if(fstab.begin(), fstab.end(),
169                                        [](const auto& entry) {
170                                            return !entry.fs_mgr_flags.first_stage_mount;
171                                        }),
172                         fstab.end());
173         } else {
174             return Error() << "failed to read default fstab for first stage mount";
175         }
176     }
177     return fstab;
178 }
179 
GetRootEntry(FstabEntry * root_entry)180 static bool GetRootEntry(FstabEntry* root_entry) {
181     Fstab proc_mounts;
182     if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
183         LOG(ERROR) << "Could not read /proc/mounts and /system not in fstab, /system will not be "
184                       "available for overlayfs";
185         return false;
186     }
187 
188     auto entry = std::find_if(proc_mounts.begin(), proc_mounts.end(), [](const auto& entry) {
189         return entry.mount_point == "/" && entry.fs_type != "rootfs";
190     });
191 
192     if (entry == proc_mounts.end()) {
193         LOG(ERROR) << "Could not get mount point for '/' in /proc/mounts, /system will not be "
194                       "available for overlayfs";
195         return false;
196     }
197 
198     *root_entry = std::move(*entry);
199 
200     // We don't know if we're avb or not, so we query device mapper as if we are avb.  If we get a
201     // success, then mark as avb, otherwise default to verify.
202     auto& dm = android::dm::DeviceMapper::Instance();
203     if (dm.GetState("vroot") != android::dm::DmDeviceState::INVALID) {
204         root_entry->fs_mgr_flags.avb = true;
205     } else {
206         root_entry->fs_mgr_flags.verify = true;
207     }
208     return true;
209 }
210 
IsStandaloneImageRollback(const AvbHandle & builtin_vbmeta,const AvbHandle & standalone_vbmeta,const FstabEntry & fstab_entry)211 static bool IsStandaloneImageRollback(const AvbHandle& builtin_vbmeta,
212                                       const AvbHandle& standalone_vbmeta,
213                                       const FstabEntry& fstab_entry) {
214     std::string old_spl = builtin_vbmeta.GetSecurityPatchLevel(fstab_entry);
215     std::string new_spl = standalone_vbmeta.GetSecurityPatchLevel(fstab_entry);
216 
217     bool rollbacked = false;
218     if (old_spl.empty() || new_spl.empty() || new_spl < old_spl) {
219         rollbacked = true;
220     }
221 
222     if (rollbacked) {
223         LOG(ERROR) << "Image rollback detected for " << fstab_entry.mount_point
224                    << ", SPL switches from '" << old_spl << "' to '" << new_spl << "'";
225         if (AvbHandle::IsDeviceUnlocked()) {
226             LOG(INFO) << "Allowing rollbacked standalone image when the device is unlocked";
227             return false;
228         }
229     }
230 
231     return rollbacked;
232 }
233 
234 // Class Definitions
235 // -----------------
FirstStageMount(Fstab fstab)236 FirstStageMount::FirstStageMount(Fstab fstab) : need_dm_verity_(false), fstab_(std::move(fstab)) {
237     super_partition_name_ = fs_mgr_get_super_partition_name();
238 }
239 
Create()240 Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
241     auto fstab = ReadFirstStageFstab();
242     if (!fstab.ok()) {
243         return fstab.error();
244     }
245 
246     if (IsDtVbmetaCompatible(*fstab)) {
247         return std::make_unique<FirstStageMountVBootV2>(std::move(*fstab));
248     } else {
249         return std::make_unique<FirstStageMountVBootV1>(std::move(*fstab));
250     }
251 }
252 
DoCreateDevices()253 bool FirstStageMount::DoCreateDevices() {
254     if (!InitDevices()) return false;
255 
256     // Mount /metadata before creating logical partitions, since we need to
257     // know whether a snapshot merge is in progress.
258     auto metadata_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
259         return entry.mount_point == "/metadata";
260     });
261     if (metadata_partition != fstab_.end()) {
262         if (MountPartition(metadata_partition, true /* erase_same_mounts */)) {
263             // Copies DSU AVB keys from the ramdisk to /metadata.
264             // Must be done before the following TrySwitchSystemAsRoot().
265             // Otherwise, ramdisk will be inaccessible after switching root.
266             CopyDsuAvbKeys();
267         }
268     }
269 
270     if (!CreateLogicalPartitions()) return false;
271 
272     return true;
273 }
274 
DoFirstStageMount()275 bool FirstStageMount::DoFirstStageMount() {
276     if (!IsDmLinearEnabled() && fstab_.empty()) {
277         // Nothing to mount.
278         LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
279         return true;
280     }
281 
282     if (!MountPartitions()) return false;
283 
284     return true;
285 }
286 
InitDevices()287 bool FirstStageMount::InitDevices() {
288     std::set<std::string> devices;
289     GetSuperDeviceName(&devices);
290 
291     if (!GetDmVerityDevices(&devices)) {
292         return false;
293     }
294     if (!InitRequiredDevices(std::move(devices))) {
295         return false;
296     }
297 
298     if (IsDmLinearEnabled()) {
299         auto super_symlink = "/dev/block/by-name/"s + super_partition_name_;
300         if (!android::base::Realpath(super_symlink, &super_path_)) {
301             PLOG(ERROR) << "realpath failed: " << super_symlink;
302             return false;
303         }
304     }
305     return true;
306 }
307 
IsDmLinearEnabled()308 bool FirstStageMount::IsDmLinearEnabled() {
309     for (const auto& entry : fstab_) {
310         if (entry.fs_mgr_flags.logical) return true;
311     }
312     return false;
313 }
314 
GetSuperDeviceName(std::set<std::string> * devices)315 void FirstStageMount::GetSuperDeviceName(std::set<std::string>* devices) {
316     // Add any additional devices required for dm-linear mappings.
317     if (!IsDmLinearEnabled()) {
318         return;
319     }
320 
321     devices->emplace(super_partition_name_);
322 }
323 
324 // Creates devices with uevent->partition_name matching ones in the given set.
325 // Found partitions will then be removed from it for the subsequent member
326 // function to check which devices are NOT created.
InitRequiredDevices(std::set<std::string> devices)327 bool FirstStageMount::InitRequiredDevices(std::set<std::string> devices) {
328     if (!block_dev_init_.InitDeviceMapper()) {
329         return false;
330     }
331     if (devices.empty()) {
332         return true;
333     }
334     return block_dev_init_.InitDevices(std::move(devices));
335 }
336 
InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata & metadata)337 bool FirstStageMount::InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata) {
338     std::set<std::string> devices;
339 
340     auto partition_names = android::fs_mgr::GetBlockDevicePartitionNames(metadata);
341     for (const auto& partition_name : partition_names) {
342         // The super partition was found in the earlier pass.
343         if (partition_name == super_partition_name_) {
344             continue;
345         }
346         devices.emplace(partition_name);
347     }
348     if (devices.empty()) {
349         return true;
350     }
351     return InitRequiredDevices(std::move(devices));
352 }
353 
CreateLogicalPartitions()354 bool FirstStageMount::CreateLogicalPartitions() {
355     if (!IsDmLinearEnabled()) {
356         return true;
357     }
358     if (super_path_.empty()) {
359         LOG(ERROR) << "Could not locate logical partition tables in partition "
360                    << super_partition_name_;
361         return false;
362     }
363 
364     if (SnapshotManager::IsSnapshotManagerNeeded()) {
365         auto sm = SnapshotManager::NewForFirstStageMount();
366         if (!sm) {
367             return false;
368         }
369         if (sm->NeedSnapshotsInFirstStageMount()) {
370             return CreateSnapshotPartitions(sm.get());
371         }
372     }
373 
374     auto metadata = android::fs_mgr::ReadCurrentMetadata(super_path_);
375     if (!metadata) {
376         LOG(ERROR) << "Could not read logical partition metadata from " << super_path_;
377         return false;
378     }
379     if (!InitDmLinearBackingDevices(*metadata.get())) {
380         return false;
381     }
382     return android::fs_mgr::CreateLogicalPartitions(*metadata.get(), super_path_);
383 }
384 
CreateSnapshotPartitions(SnapshotManager * sm)385 bool FirstStageMount::CreateSnapshotPartitions(SnapshotManager* sm) {
386     // When COW images are present for snapshots, they are stored on
387     // the data partition.
388     if (!InitRequiredDevices({"userdata"})) {
389         return false;
390     }
391 
392     use_snapuserd_ = sm->IsSnapuserdRequired();
393     if (use_snapuserd_) {
394         LaunchFirstStageSnapuserd();
395     }
396 
397     sm->SetUeventRegenCallback([this](const std::string& device) -> bool {
398         if (android::base::StartsWith(device, "/dev/block/dm-")) {
399             return block_dev_init_.InitDmDevice(device);
400         }
401         if (android::base::StartsWith(device, "/dev/dm-user/")) {
402             return block_dev_init_.InitDmUser(android::base::Basename(device));
403         }
404         return block_dev_init_.InitDevices({device});
405     });
406     if (!sm->CreateLogicalAndSnapshotPartitions(super_path_)) {
407         return false;
408     }
409 
410     if (use_snapuserd_) {
411         CleanupSnapuserdSocket();
412     }
413     return true;
414 }
415 
MountPartition(const Fstab::iterator & begin,bool erase_same_mounts,Fstab::iterator * end)416 bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
417                                      Fstab::iterator* end) {
418     // Sets end to begin + 1, so we can just return on failure below.
419     if (end) {
420         *end = begin + 1;
421     }
422 
423     if (!fs_mgr_create_canonical_mount_point(begin->mount_point)) {
424         return false;
425     }
426 
427     if (begin->fs_mgr_flags.logical) {
428         if (!fs_mgr_update_logical_partition(&(*begin))) {
429             return false;
430         }
431         if (!block_dev_init_.InitDmDevice(begin->blk_device)) {
432             return false;
433         }
434     }
435     if (!SetUpDmVerity(&(*begin))) {
436         PLOG(ERROR) << "Failed to setup verity for '" << begin->mount_point << "'";
437         return false;
438     }
439 
440     bool mounted = (fs_mgr_do_mount_one(*begin) == 0);
441 
442     // Try other mounts with the same mount point.
443     Fstab::iterator current = begin + 1;
444     for (; current != fstab_.end() && current->mount_point == begin->mount_point; current++) {
445         if (!mounted) {
446             // blk_device is already updated to /dev/dm-<N> by SetUpDmVerity() above.
447             // Copy it from the begin iterator.
448             current->blk_device = begin->blk_device;
449             mounted = (fs_mgr_do_mount_one(*current) == 0);
450         }
451     }
452     if (erase_same_mounts) {
453         current = fstab_.erase(begin, current);
454     }
455     if (end) {
456         *end = current;
457     }
458     return mounted;
459 }
460 
PreloadAvbKeys()461 void FirstStageMount::PreloadAvbKeys() {
462     for (const auto& entry : fstab_) {
463         // No need to cache the key content if it's empty, or is already cached.
464         if (entry.avb_keys.empty() || preload_avb_key_blobs_.count(entry.avb_keys)) {
465             continue;
466         }
467 
468         // Determines all key paths first.
469         std::vector<std::string> key_paths;
470         if (is_dir(entry.avb_keys.c_str())) {  // fstab_keys might be a dir, e.g., /avb.
471             const char* avb_key_dir = entry.avb_keys.c_str();
472             std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(avb_key_dir), closedir);
473             if (!dir) {
474                 LOG(ERROR) << "Failed to opendir: " << dir;
475                 continue;
476             }
477             // Gets all key pathes under the dir.
478             struct dirent* de;
479             while ((de = readdir(dir.get()))) {
480                 if (de->d_type != DT_REG) continue;
481                 std::string full_path = StringPrintf("%s/%s", avb_key_dir, de->d_name);
482                 key_paths.emplace_back(std::move(full_path));
483             }
484             std::sort(key_paths.begin(), key_paths.end());
485         } else {
486             // avb_keys are key paths separated by ":", if it's not a dir.
487             key_paths = Split(entry.avb_keys, ":");
488         }
489 
490         // Reads the key content then cache it.
491         std::vector<std::string> key_blobs;
492         for (const auto& path : key_paths) {
493             std::string key_value;
494             if (!ReadFileToString(path, &key_value)) {
495                 continue;
496             }
497             key_blobs.emplace_back(std::move(key_value));
498         }
499 
500         // Maps entry.avb_keys to actual key blobs.
501         preload_avb_key_blobs_[entry.avb_keys] = std::move(key_blobs);
502     }
503 }
504 
505 // If system is in the fstab then we're not a system-as-root device, and in
506 // this case, we mount system first then pivot to it.  From that point on,
507 // we are effectively identical to a system-as-root device.
TrySwitchSystemAsRoot()508 bool FirstStageMount::TrySwitchSystemAsRoot() {
509     UseDsuIfPresent();
510     // Preloading all AVB keys from the ramdisk before switching root to /system.
511     PreloadAvbKeys();
512 
513     auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
514         return entry.mount_point == "/system";
515     });
516 
517     if (system_partition == fstab_.end()) return true;
518 
519     if (use_snapuserd_) {
520         SaveRamdiskPathToSnapuserd();
521     }
522 
523     if (MountPartition(system_partition, false /* erase_same_mounts */)) {
524         if (dsu_not_on_userdata_ && fs_mgr_verity_is_check_at_most_once(*system_partition)) {
525             LOG(ERROR) << "check_most_at_once forbidden on external media";
526             return false;
527         }
528         SwitchRoot("/system");
529     } else {
530         PLOG(ERROR) << "Failed to mount /system";
531         return false;
532     }
533 
534     return true;
535 }
536 
MountPartitions()537 bool FirstStageMount::MountPartitions() {
538     if (!TrySwitchSystemAsRoot()) return false;
539 
540     if (!SkipMountingPartitions(&fstab_, true /* verbose */)) return false;
541 
542     for (auto current = fstab_.begin(); current != fstab_.end();) {
543         // We've already mounted /system above.
544         if (current->mount_point == "/system") {
545             ++current;
546             continue;
547         }
548 
549         // Handle overlayfs entries later.
550         if (current->fs_type == "overlay") {
551             ++current;
552             continue;
553         }
554 
555         // Skip raw partition entries such as boot, dtbo, etc.
556         // Having emmc fstab entries allows us to probe current->vbmeta_partition
557         // in InitDevices() when they are AVB chained partitions.
558         if (current->fs_type == "emmc") {
559             ++current;
560             continue;
561         }
562 
563         Fstab::iterator end;
564         if (!MountPartition(current, false /* erase_same_mounts */, &end)) {
565             if (current->fs_mgr_flags.no_fail) {
566                 LOG(INFO) << "Failed to mount " << current->mount_point
567                           << ", ignoring mount for no_fail partition";
568             } else if (current->fs_mgr_flags.formattable) {
569                 LOG(INFO) << "Failed to mount " << current->mount_point
570                           << ", ignoring mount for formattable partition";
571             } else {
572                 PLOG(ERROR) << "Failed to mount " << current->mount_point;
573                 return false;
574             }
575         }
576         current = end;
577     }
578 
579     for (const auto& entry : fstab_) {
580         if (entry.fs_type == "overlay") {
581             fs_mgr_mount_overlayfs_fstab_entry(entry);
582         }
583     }
584 
585     // If we don't see /system or / in the fstab, then we need to create an root entry for
586     // overlayfs.
587     if (!GetEntryForMountPoint(&fstab_, "/system") && !GetEntryForMountPoint(&fstab_, "/")) {
588         FstabEntry root_entry;
589         if (GetRootEntry(&root_entry)) {
590             fstab_.emplace_back(std::move(root_entry));
591         }
592     }
593 
594     // heads up for instantiating required device(s) for overlayfs logic
595     auto init_devices = [this](std::set<std::string> devices) -> bool {
596         for (auto iter = devices.begin(); iter != devices.end();) {
597             if (android::base::StartsWith(*iter, "/dev/block/dm-")) {
598                 if (!block_dev_init_.InitDmDevice(*iter)) {
599                     return false;
600                 }
601                 iter = devices.erase(iter);
602             } else {
603                 iter++;
604             }
605         }
606         return InitRequiredDevices(std::move(devices));
607     };
608     MapScratchPartitionIfNeeded(&fstab_, init_devices);
609 
610     fs_mgr_overlayfs_mount_all(&fstab_);
611 
612     return true;
613 }
614 
615 // Preserves /avb/*.avbpubkey to /metadata/gsi/dsu/avb/, so they can be used for
616 // key revocation check by DSU installation service.  Note that failing to
617 // copy files to /metadata is NOT fatal, because it is auxiliary to perform
618 // public key matching before booting into DSU images on next boot. The actual
619 // public key matching will still be done on next boot to DSU.
CopyDsuAvbKeys()620 void FirstStageMount::CopyDsuAvbKeys() {
621     std::error_code ec;
622     // Removing existing keys in gsi::kDsuAvbKeyDir as they might be stale.
623     std::filesystem::remove_all(gsi::kDsuAvbKeyDir, ec);
624     if (ec) {
625         LOG(ERROR) << "Failed to remove directory " << gsi::kDsuAvbKeyDir << ": " << ec.message();
626     }
627     // Copy keys from the ramdisk /avb/* to gsi::kDsuAvbKeyDir.
628     static constexpr char kRamdiskAvbKeyDir[] = "/avb";
629     std::filesystem::copy(kRamdiskAvbKeyDir, gsi::kDsuAvbKeyDir, ec);
630     if (ec) {
631         LOG(ERROR) << "Failed to copy " << kRamdiskAvbKeyDir << " into " << gsi::kDsuAvbKeyDir
632                    << ": " << ec.message();
633     }
634 }
635 
UseDsuIfPresent()636 void FirstStageMount::UseDsuIfPresent() {
637     std::string error;
638 
639     if (!android::gsi::CanBootIntoGsi(&error)) {
640         LOG(INFO) << "DSU " << error << ", proceeding with normal boot";
641         return;
642     }
643 
644     auto init_devices = [this](std::set<std::string> devices) -> bool {
645         if (devices.count("userdata") == 0 || devices.size() > 1) {
646             dsu_not_on_userdata_ = true;
647         }
648         return InitRequiredDevices(std::move(devices));
649     };
650     std::string active_dsu;
651     if (!gsi::GetActiveDsu(&active_dsu)) {
652         LOG(ERROR) << "Failed to GetActiveDsu";
653         return;
654     }
655     LOG(INFO) << "DSU slot: " << active_dsu;
656     auto images = IImageManager::Open("dsu/" + active_dsu, 0ms);
657     if (!images || !images->MapAllImages(init_devices)) {
658         LOG(ERROR) << "DSU partition layout could not be instantiated";
659         return;
660     }
661 
662     if (!android::gsi::MarkSystemAsGsi()) {
663         PLOG(ERROR) << "DSU indicator file could not be written";
664         return;
665     }
666 
667     std::string lp_names = "";
668     std::vector<std::string> dsu_partitions;
669     for (auto&& name : images->GetAllBackingImages()) {
670         dsu_partitions.push_back(name);
671         lp_names += name + ",";
672     }
673     // Publish the logical partition names for TransformFstabForDsu
674     WriteFile(gsi::kGsiLpNamesFile, lp_names);
675     TransformFstabForDsu(&fstab_, active_dsu, dsu_partitions);
676 }
677 
GetDmVerityDevices(std::set<std::string> * devices)678 bool FirstStageMountVBootV1::GetDmVerityDevices(std::set<std::string>* devices) {
679     need_dm_verity_ = false;
680 
681     for (const auto& fstab_entry : fstab_) {
682         // Don't allow verifyatboot in the first stage.
683         if (fstab_entry.fs_mgr_flags.verify_at_boot) {
684             LOG(ERROR) << "Partitions can't be verified at boot";
685             return false;
686         }
687         // Checks for verified partitions.
688         if (fstab_entry.fs_mgr_flags.verify) {
689             need_dm_verity_ = true;
690         }
691     }
692 
693     // Includes the partition names of fstab records.
694     // Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used.
695     for (const auto& fstab_entry : fstab_) {
696         // Skip pseudo filesystems.
697         if (fstab_entry.fs_type == "overlay") {
698             continue;
699         }
700         if (!fstab_entry.fs_mgr_flags.logical) {
701             devices->emplace(basename(fstab_entry.blk_device.c_str()));
702         }
703     }
704 
705     return true;
706 }
707 
SetUpDmVerity(FstabEntry * fstab_entry)708 bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) {
709     if (fstab_entry->fs_mgr_flags.verify) {
710         int ret = fs_mgr_setup_verity(fstab_entry, false /* wait_for_verity_dev */);
711         switch (ret) {
712             case FS_MGR_SETUP_VERITY_SKIPPED:
713             case FS_MGR_SETUP_VERITY_DISABLED:
714                 LOG(INFO) << "Verity disabled/skipped for '" << fstab_entry->mount_point << "'";
715                 return true;
716             case FS_MGR_SETUP_VERITY_SUCCESS:
717                 // The exact block device name (fstab_rec->blk_device) is changed to
718                 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
719                 // first stage.
720                 return block_dev_init_.InitDmDevice(fstab_entry->blk_device);
721             default:
722                 return false;
723         }
724     }
725     return true;  // Returns true to mount the partition.
726 }
727 
728 // First retrieve any vbmeta partitions from device tree (legacy) then read through the fstab
729 // for any further vbmeta partitions.
FirstStageMountVBootV2(Fstab fstab)730 FirstStageMountVBootV2::FirstStageMountVBootV2(Fstab fstab)
731     : FirstStageMount(std::move(fstab)), avb_handle_(nullptr) {
732     std::string device_tree_vbmeta_parts;
733     read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts);
734 
735     for (auto&& partition : Split(device_tree_vbmeta_parts, ",")) {
736         if (!partition.empty()) {
737             vbmeta_partitions_.emplace_back(std::move(partition));
738         }
739     }
740 
741     for (const auto& entry : fstab_) {
742         if (!entry.vbmeta_partition.empty()) {
743             vbmeta_partitions_.emplace_back(entry.vbmeta_partition);
744         }
745     }
746 
747     if (vbmeta_partitions_.empty()) {
748         LOG(ERROR) << "Failed to read vbmeta partitions.";
749     }
750 }
751 
GetDmVerityDevices(std::set<std::string> * devices)752 bool FirstStageMountVBootV2::GetDmVerityDevices(std::set<std::string>* devices) {
753     need_dm_verity_ = false;
754 
755     std::set<std::string> logical_partitions;
756 
757     // fstab_rec->blk_device has A/B suffix.
758     for (const auto& fstab_entry : fstab_) {
759         if (fstab_entry.fs_mgr_flags.avb) {
760             need_dm_verity_ = true;
761         }
762         // Skip pseudo filesystems.
763         if (fstab_entry.fs_type == "overlay") {
764             continue;
765         }
766         if (fstab_entry.fs_mgr_flags.logical) {
767             // Don't try to find logical partitions via uevent regeneration.
768             logical_partitions.emplace(basename(fstab_entry.blk_device.c_str()));
769         } else {
770             devices->emplace(basename(fstab_entry.blk_device.c_str()));
771         }
772     }
773 
774     // Any partitions needed for verifying the partitions used in first stage mount, e.g. vbmeta
775     // must be provided as vbmeta_partitions.
776     if (need_dm_verity_) {
777         if (vbmeta_partitions_.empty()) {
778             LOG(ERROR) << "Missing vbmeta partitions";
779             return false;
780         }
781         std::string ab_suffix = fs_mgr_get_slot_suffix();
782         for (const auto& partition : vbmeta_partitions_) {
783             std::string partition_name = partition + ab_suffix;
784             if (logical_partitions.count(partition_name)) {
785                 continue;
786             }
787             // devices is of type std::set so it's not an issue to emplace a
788             // partition twice. e.g., /vendor might be in both places:
789             //   - device_tree_vbmeta_parts_ = "vbmeta,boot,system,vendor"
790             //   - mount_fstab_recs_: /vendor_a
791             devices->emplace(partition_name);
792         }
793     }
794     return true;
795 }
796 
SetUpDmVerity(FstabEntry * fstab_entry)797 bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
798     AvbHashtreeResult hashtree_result;
799 
800     // It's possible for a fstab_entry to have both avb_keys and avb flag.
801     // In this case, try avb_keys first, then fallback to avb flag.
802     if (!fstab_entry->avb_keys.empty()) {
803         if (!InitAvbHandle()) return false;
804         // Checks if hashtree should be disabled from the top-level /vbmeta.
805         if (avb_handle_->status() == AvbHandleStatus::kHashtreeDisabled ||
806             avb_handle_->status() == AvbHandleStatus::kVerificationDisabled) {
807             LOG(ERROR) << "Top-level vbmeta is disabled, skip Hashtree setup for "
808                        << fstab_entry->mount_point;
809             return true;  // Returns true to mount the partition directly.
810         } else {
811             auto avb_standalone_handle = AvbHandle::LoadAndVerifyVbmeta(
812                     *fstab_entry, preload_avb_key_blobs_[fstab_entry->avb_keys]);
813             if (!avb_standalone_handle) {
814                 LOG(ERROR) << "Failed to load offline vbmeta for " << fstab_entry->mount_point;
815                 // Fallbacks to built-in hashtree if fs_mgr_flags.avb is set.
816                 if (!fstab_entry->fs_mgr_flags.avb) return false;
817                 LOG(INFO) << "Fallback to built-in hashtree for " << fstab_entry->mount_point;
818                 hashtree_result =
819                         avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
820             } else {
821                 // Sets up hashtree via the standalone handle.
822                 if (IsStandaloneImageRollback(*avb_handle_, *avb_standalone_handle, *fstab_entry)) {
823                     return false;
824                 }
825                 hashtree_result = avb_standalone_handle->SetUpAvbHashtree(
826                         fstab_entry, false /* wait_for_verity_dev */);
827             }
828         }
829     } else if (fstab_entry->fs_mgr_flags.avb) {
830         if (!InitAvbHandle()) return false;
831         hashtree_result =
832                 avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
833     } else {
834         return true;  // No need AVB, returns true to mount the partition directly.
835     }
836 
837     switch (hashtree_result) {
838         case AvbHashtreeResult::kDisabled:
839             return true;  // Returns true to mount the partition.
840         case AvbHashtreeResult::kSuccess:
841             // The exact block device name (fstab_rec->blk_device) is changed to
842             // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
843             // first stage.
844             return block_dev_init_.InitDmDevice(fstab_entry->blk_device);
845         default:
846             return false;
847     }
848 }
849 
InitAvbHandle()850 bool FirstStageMountVBootV2::InitAvbHandle() {
851     if (avb_handle_) return true;  // Returns true if the handle is already initialized.
852 
853     avb_handle_ = AvbHandle::Open();
854 
855     if (!avb_handle_) {
856         PLOG(ERROR) << "Failed to open AvbHandle";
857         return false;
858     }
859     // Sets INIT_AVB_VERSION here for init to set ro.boot.avb_version in the second stage.
860     setenv("INIT_AVB_VERSION", avb_handle_->avb_version().c_str(), 1);
861     return true;
862 }
863 
864 // Public functions
865 // ----------------
866 // Creates devices and logical partitions from storage devices
DoCreateDevices()867 bool DoCreateDevices() {
868     auto fsm = FirstStageMount::Create();
869     if (!fsm.ok()) {
870         LOG(ERROR) << "Failed to create FirstStageMount: " << fsm.error();
871         return false;
872     }
873     return (*fsm)->DoCreateDevices();
874 }
875 
876 // Mounts partitions specified by fstab in device tree.
DoFirstStageMount(bool create_devices)877 bool DoFirstStageMount(bool create_devices) {
878     // Skips first stage mount if we're in recovery mode.
879     if (IsRecoveryMode()) {
880         LOG(INFO) << "First stage mount skipped (recovery mode)";
881         return true;
882     }
883 
884     auto fsm = FirstStageMount::Create();
885     if (!fsm.ok()) {
886         LOG(ERROR) << "Failed to create FirstStageMount " << fsm.error();
887         return false;
888     }
889 
890     if (create_devices) {
891         if (!(*fsm)->DoCreateDevices()) return false;
892     }
893 
894     return (*fsm)->DoFirstStageMount();
895 }
896 
SetInitAvbVersionInRecovery()897 void SetInitAvbVersionInRecovery() {
898     if (!IsRecoveryMode()) {
899         LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not in recovery mode)";
900         return;
901     }
902 
903     auto fstab = ReadFirstStageFstab();
904     if (!fstab.ok()) {
905         LOG(ERROR) << fstab.error();
906         return;
907     }
908 
909     if (!IsDtVbmetaCompatible(*fstab)) {
910         LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
911         return;
912     }
913 
914     // Initializes required devices for the subsequent AvbHandle::Open()
915     // to verify AVB metadata on all partitions in the verified chain.
916     // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the
917     // Open() function returns a valid handle.
918     // We don't need to mount partitions here in recovery mode.
919     FirstStageMountVBootV2 avb_first_mount(std::move(*fstab));
920     if (!avb_first_mount.InitDevices()) {
921         LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION";
922         return;
923     }
924 
925     AvbUniquePtr avb_handle = AvbHandle::Open();
926     if (!avb_handle) {
927         PLOG(ERROR) << "Failed to open AvbHandle for INIT_AVB_VERSION";
928         return;
929     }
930     setenv("INIT_AVB_VERSION", avb_handle->avb_version().c_str(), 1);
931 }
932 
933 }  // namespace init
934 }  // namespace android
935