1 // 2 // Copyright (C) 2012 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 #ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FILESYSTEM_VERIFIER_ACTION_H_ 18 #define UPDATE_ENGINE_PAYLOAD_CONSUMER_FILESYSTEM_VERIFIER_ACTION_H_ 19 20 #include <sys/stat.h> 21 #include <sys/types.h> 22 23 #include <memory> 24 #include <string> 25 #include <vector> 26 27 #include <brillo/streams/stream.h> 28 29 #include "update_engine/common/action.h" 30 #include "update_engine/common/hash_calculator.h" 31 #include "update_engine/payload_consumer/install_plan.h" 32 #include "update_engine/payload_consumer/verity_writer_interface.h" 33 34 // This action will hash all the partitions of the target slot involved in the 35 // update. The hashes are then verified against the ones in the InstallPlan. 36 // If the target hash does not match, the action will fail. In case of failure, 37 // the error code will depend on whether the source slot hashes are provided and 38 // match. 39 40 namespace chromeos_update_engine { 41 42 // The step FilesystemVerifier is on. On kVerifyTargetHash it computes the hash 43 // on the target partitions based on the already populated size and verifies it 44 // matches the one in the target_hash in the InstallPlan. 45 // If the hash matches, then we skip the kVerifySourceHash step, otherwise we 46 // need to check if the source is the root cause of the mismatch. 47 enum class VerifierStep { 48 kVerifyTargetHash, 49 kVerifySourceHash, 50 }; 51 52 class FilesystemVerifierAction : public InstallPlanAction { 53 public: FilesystemVerifierAction()54 FilesystemVerifierAction() 55 : verity_writer_(verity_writer::CreateVerityWriter()) {} 56 ~FilesystemVerifierAction() override = default; 57 58 void PerformAction() override; 59 void TerminateProcessing() override; 60 61 // Debugging/logging StaticType()62 static std::string StaticType() { return "FilesystemVerifierAction"; } Type()63 std::string Type() const override { return StaticType(); } 64 65 private: 66 friend class FilesystemVerifierActionTestDelegate; 67 // Starts the hashing of the current partition. If there aren't any partitions 68 // remaining to be hashed, it finishes the action. 69 void StartPartitionHashing(); 70 71 // Schedules the asynchronous read of the filesystem. 72 void ScheduleRead(); 73 74 // Called from the main loop when a single read from |src_stream_| succeeds or 75 // fails, calling OnReadDoneCallback() and OnReadErrorCallback() respectively. 76 void OnReadDoneCallback(size_t bytes_read); 77 void OnReadErrorCallback(const brillo::Error* error); 78 79 // When the read is done, finalize the hash checking of the current partition 80 // and continue checking the next one. 81 void FinishPartitionHashing(); 82 83 // Cleans up all the variables we use for async operations and tells the 84 // ActionProcessor we're done w/ |code| as passed in. |cancelled_| should be 85 // true if TerminateProcessing() was called. 86 void Cleanup(ErrorCode code); 87 88 // The type of the partition that we are verifying. 89 VerifierStep verifier_step_ = VerifierStep::kVerifyTargetHash; 90 91 // The index in the install_plan_.partitions vector of the partition currently 92 // being hashed. 93 size_t partition_index_{0}; 94 95 // If not null, the FileStream used to read from the device. 96 brillo::StreamPtr src_stream_; 97 98 // Buffer for storing data we read. 99 brillo::Blob buffer_; 100 101 bool cancelled_{false}; // true if the action has been cancelled. 102 103 // The install plan we're passed in via the input pipe. 104 InstallPlan install_plan_; 105 106 // Calculates the hash of the data. 107 std::unique_ptr<HashCalculator> hasher_; 108 109 // Write verity data of the current partition. 110 std::unique_ptr<VerityWriterInterface> verity_writer_; 111 112 // Reads and hashes this many bytes from the head of the input stream. When 113 // the partition starts to be hashed, this field is initialized from the 114 // corresponding InstallPlan::Partition size which is the total size 115 // update_engine is expected to write, and may be smaller than the size of the 116 // partition in gpt. 117 uint64_t partition_size_{0}; 118 119 // The byte offset that we are reading in the current partition. 120 uint64_t offset_{0}; 121 122 DISALLOW_COPY_AND_ASSIGN(FilesystemVerifierAction); 123 }; 124 125 } // namespace chromeos_update_engine 126 127 #endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_FILESYSTEM_VERIFIER_ACTION_H_ 128