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