• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/core


Commit MetaInfo

修訂7a4fb7a435459222b718ceb4607fb0577a7ed8a9 (tree)
時間2019-04-11 10:44:13
作者Bowgo Tsai <bowgotsai@goog...>
CommiterBowgo Tsai

Log Message

first-stage mount: support using other avb_keys

This change allows specifying additional avb keys to verify a fstab
entry. It can be used together with the original 'avb' flag. When both
'avb' and 'avb_keys' are present, it will try to use avb_keys to verify
this partition and extract the AVB descriptor from the end of it first.
When avb_key fails, it falls back to searching the AVB descriptor in the
built-in /vbmeta (and its chained partitions) with the matched partition
name.

An example of a fstab file:

system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta,logical,first_stage_mount,avb_keys=/avb/gsi.avbpubkey
vendor /vendor ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount

The overhead of adding an additional 'avb_keys' should not be significant,
as the typical size of a AVB Hashtree descriptor for /system is usually
less than 1000 bytes. e.g., on crosshatch, it's about 600 bytes, which
takes less than 1 millisecond for the following call to return failure.

auto avb_standalone_handle = AvbHandle::LoadAndVerifyVbmeta(*fstab_entry);

We also checked the time spent on init's first stage on crosshatch, with the
following CL to set ro.boottime.init.first_stage. The testing result
shows no significant difference between them as well.

https://android-review.googlesource.com/c/platform/system/core/+/934536

With an additional avb_keys entry for /system

[ro.boottime.init.first_stage]: [728]
[ro.boottime.init.first_stage]: [720]
[ro.boottime.init.first_stage]: [722]

Without an additional avb_keys entry for /system

[ro.boottime.init.first_stage]: [730]
[ro.boottime.init.first_stage]: [728]
[ro.boottime.init.first_stage]: [725]

Bug: 124491153
Test: boot a device with above fstab settings

Change-Id: I0c81f816efb0dd40c93da2df304f2e215df9d105
Merged-In: I0c81f816efb0dd40c93da2df304f2e215df9d105
(cherry picked from commit a0f8b05d913855e3d8e9836f124fc9fdc755d450)

Change Summary

差異

--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -80,7 +80,7 @@ class FirstStageMount {
8080 bool InitMappedDevice(const std::string& verity_device);
8181 bool InitDeviceMapper();
8282 bool CreateLogicalPartitions();
83- bool MountPartition(const Fstab::iterator& begin, bool erase_used_fstab_entry,
83+ bool MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
8484 Fstab::iterator* end = nullptr);
8585
8686 bool MountPartitions();
@@ -437,21 +437,26 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
437437
438438 uevent_listener_.RegenerateUeventsForPath(syspath, verity_callback);
439439 if (!found) {
440- LOG(INFO) << "dm-verity device not found in /sys, waiting for its uevent";
440+ LOG(INFO) << "dm device '" << dm_device << "' not found in /sys, waiting for its uevent";
441441 Timer t;
442442 uevent_listener_.Poll(verity_callback, 10s);
443- LOG(INFO) << "wait for dm-verity device returned after " << t;
443+ LOG(INFO) << "wait for dm device '" << dm_device << "' returned after " << t;
444444 }
445445 if (!found) {
446- LOG(ERROR) << "dm-verity device not found after polling timeout";
446+ LOG(ERROR) << "dm device '" << dm_device << "' not found after polling timeout";
447447 return false;
448448 }
449449
450450 return true;
451451 }
452452
453-bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_used_fstab_entry,
453+bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
454454 Fstab::iterator* end) {
455+ // Sets end to begin + 1, so we can just return on failure below.
456+ if (end) {
457+ *end = begin + 1;
458+ }
459+
455460 if (begin->fs_mgr_flags.logical) {
456461 if (!fs_mgr_update_logical_partition(&(*begin))) {
457462 return false;
@@ -477,7 +482,7 @@ bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_us
477482 mounted = (fs_mgr_do_mount_one(*current) == 0);
478483 }
479484 }
480- if (erase_used_fstab_entry) {
485+ if (erase_same_mounts) {
481486 current = fstab_.erase(begin, current);
482487 }
483488 if (end) {
@@ -494,7 +499,7 @@ bool FirstStageMount::TrySwitchSystemAsRoot() {
494499 return entry.mount_point == "/metadata";
495500 });
496501 if (metadata_partition != fstab_.end()) {
497- if (MountPartition(metadata_partition, true /* erase_used_fstab_entry */)) {
502+ if (MountPartition(metadata_partition, true /* erase_same_mounts */)) {
498503 UseGsiIfPresent();
499504 }
500505 }
@@ -505,7 +510,7 @@ bool FirstStageMount::TrySwitchSystemAsRoot() {
505510
506511 if (system_partition == fstab_.end()) return true;
507512
508- if (MountPartition(system_partition, false)) {
513+ if (MountPartition(system_partition, false /* erase_same_mounts */)) {
509514 if (gsi_not_on_userdata_ && fs_mgr_verity_is_check_at_most_once(*system_partition)) {
510515 LOG(ERROR) << "check_most_at_once forbidden on external media";
511516 return false;
@@ -560,7 +565,7 @@ bool FirstStageMount::MountPartitions() {
560565 }
561566
562567 Fstab::iterator end;
563- if (!MountPartition(current, false, &end)) {
568+ if (!MountPartition(current, false /* erase_same_mounts */, &end)) {
564569 if (current->fs_mgr_flags.no_fail) {
565570 LOG(INFO) << "Failed to mount " << current->mount_point
566571 << ", ignoring mount for no_fail partition";
@@ -797,11 +802,9 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() {
797802 bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
798803 AvbHashtreeResult hashtree_result;
799804
800- if (fstab_entry->fs_mgr_flags.avb) {
801- if (!InitAvbHandle()) return false;
802- hashtree_result =
803- avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
804- } else if (!fstab_entry->avb_keys.empty()) {
805+ // It's possible for a fstab_entry to have both avb_keys and avb flag.
806+ // In this case, try avb_keys first, then fallback to avb flag.
807+ if (!fstab_entry->avb_keys.empty()) {
805808 if (!InitAvbHandle()) return false;
806809 // Checks if hashtree should be disabled from the top-level /vbmeta.
807810 if (avb_handle_->status() == AvbHandleStatus::kHashtreeDisabled ||
@@ -813,14 +816,24 @@ bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
813816 auto avb_standalone_handle = AvbHandle::LoadAndVerifyVbmeta(*fstab_entry);
814817 if (!avb_standalone_handle) {
815818 LOG(ERROR) << "Failed to load offline vbmeta for " << fstab_entry->mount_point;
816- return false;
817- }
818- if (IsStandaloneImageRollback(*avb_handle_, *avb_standalone_handle, *fstab_entry)) {
819- return false;
819+ // Fallbacks to built-in hashtree if fs_mgr_flags.avb is set.
820+ if (!fstab_entry->fs_mgr_flags.avb) return false;
821+ LOG(INFO) << "Fallback to built-in hashtree for " << fstab_entry->mount_point;
822+ hashtree_result =
823+ avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
824+ } else {
825+ // Sets up hashtree via the standalone handle.
826+ if (IsStandaloneImageRollback(*avb_handle_, *avb_standalone_handle, *fstab_entry)) {
827+ return false;
828+ }
829+ hashtree_result = avb_standalone_handle->SetUpAvbHashtree(
830+ fstab_entry, false /* wait_for_verity_dev */);
820831 }
821- hashtree_result = avb_standalone_handle->SetUpAvbHashtree(
822- fstab_entry, false /* wait_for_verity_dev */);
823832 }
833+ } else if (fstab_entry->fs_mgr_flags.avb) {
834+ if (!InitAvbHandle()) return false;
835+ hashtree_result =
836+ avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
824837 } else {
825838 return true; // No need AVB, returns true to mount the partition directly.
826839 }