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 "init_first_stage.h" 18 19 #include <stdlib.h> 20 #include <unistd.h> 21 22 #include <memory> 23 #include <set> 24 #include <string> 25 #include <vector> 26 27 #include <android-base/file.h> 28 #include <android-base/logging.h> 29 #include <android-base/strings.h> 30 31 #include "devices.h" 32 #include "fs_mgr.h" 33 #include "fs_mgr_avb.h" 34 #include "util.h" 35 36 // Class Declarations 37 // ------------------ 38 class FirstStageMount { 39 public: 40 FirstStageMount(); 41 virtual ~FirstStageMount() = default; 42 43 // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2 44 // based on device tree configurations. 45 static std::unique_ptr<FirstStageMount> Create(); 46 bool DoFirstStageMount(); // Mounts fstab entries read from device tree. 47 bool InitDevices(); 48 49 protected: 50 void InitRequiredDevices(); 51 void InitVerityDevice(const std::string& verity_device); 52 bool MountPartitions(); 53 54 virtual coldboot_action_t ColdbootCallback(uevent* uevent); 55 56 // Pure virtual functions. 57 virtual bool GetRequiredDevices() = 0; 58 virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; 59 60 bool need_dm_verity_; 61 // Device tree fstab entries. 62 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_; 63 // Eligible first stage mount candidates, only allow /system, /vendor and/or /odm. 64 std::vector<fstab_rec*> mount_fstab_recs_; 65 std::set<std::string> required_devices_partition_names_; 66 }; 67 68 class FirstStageMountVBootV1 : public FirstStageMount { 69 public: 70 FirstStageMountVBootV1() = default; 71 ~FirstStageMountVBootV1() override = default; 72 73 protected: 74 bool GetRequiredDevices() override; 75 bool SetUpDmVerity(fstab_rec* fstab_rec) override; 76 }; 77 78 class FirstStageMountVBootV2 : public FirstStageMount { 79 public: 80 friend void SetInitAvbVersionInRecovery(); 81 82 FirstStageMountVBootV2(); 83 ~FirstStageMountVBootV2() override = default; 84 85 protected: 86 coldboot_action_t ColdbootCallback(uevent* uevent) override; 87 bool GetRequiredDevices() override; 88 bool SetUpDmVerity(fstab_rec* fstab_rec) override; 89 bool InitAvbHandle(); 90 91 std::string device_tree_vbmeta_parts_; 92 FsManagerAvbUniquePtr avb_handle_; 93 ByNameSymlinkMap by_name_symlink_map_; 94 }; 95 96 // Static Functions 97 // ---------------- 98 static inline bool IsDtVbmetaCompatible() { 99 return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta"); 100 } 101 102 static bool inline IsRecoveryMode() { 103 return access("/sbin/recovery", F_OK) == 0; 104 } 105 106 // Class Definitions 107 // ----------------- 108 FirstStageMount::FirstStageMount() 109 : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) { 110 if (!device_tree_fstab_) { 111 LOG(ERROR) << "Failed to read fstab from device tree"; 112 return; 113 } 114 for (auto mount_point : {"/system", "/vendor", "/odm"}) { 115 fstab_rec* fstab_rec = 116 fs_mgr_get_entry_for_mount_point(device_tree_fstab_.get(), mount_point); 117 if (fstab_rec != nullptr) { 118 mount_fstab_recs_.push_back(fstab_rec); 119 } 120 } 121 } 122 123 std::unique_ptr<FirstStageMount> FirstStageMount::Create() { 124 if (IsDtVbmetaCompatible()) { 125 return std::make_unique<FirstStageMountVBootV2>(); 126 } else { 127 return std::make_unique<FirstStageMountVBootV1>(); 128 } 129 } 130 131 bool FirstStageMount::DoFirstStageMount() { 132 // Nothing to mount. 133 if (mount_fstab_recs_.empty()) return true; 134 135 if (!InitDevices()) return false; 136 137 if (!MountPartitions()) return false; 138 139 return true; 140 } 141 142 bool FirstStageMount::InitDevices() { 143 if (!GetRequiredDevices()) return false; 144 145 InitRequiredDevices(); 146 147 // InitRequiredDevices() will remove found partitions from required_devices_partition_names_. 148 // So if it isn't empty here, it means some partitions are not found. 149 if (!required_devices_partition_names_.empty()) { 150 LOG(ERROR) << __FUNCTION__ << "(): partition(s) not found: " 151 << android::base::Join(required_devices_partition_names_, ", "); 152 return false; 153 } else { 154 return true; 155 } 156 } 157 158 // Creates devices with uevent->partition_name matching one in the member variable 159 // required_devices_partition_names_. Found partitions will then be removed from it 160 // for the subsequent member function to check which devices are NOT created. 161 void FirstStageMount::InitRequiredDevices() { 162 if (required_devices_partition_names_.empty()) { 163 return; 164 } 165 166 if (need_dm_verity_) { 167 const std::string dm_path = "/devices/virtual/misc/device-mapper"; 168 device_init(("/sys" + dm_path).c_str(), [&dm_path](uevent* uevent) -> coldboot_action_t { 169 if (uevent->path && uevent->path == dm_path) return COLDBOOT_STOP; 170 return COLDBOOT_CONTINUE; // dm_path not found, continue to find it. 171 }); 172 } 173 174 device_init(nullptr, 175 [this](uevent* uevent) -> coldboot_action_t { return ColdbootCallback(uevent); }); 176 177 device_close(); 178 } 179 180 coldboot_action_t FirstStageMount::ColdbootCallback(uevent* uevent) { 181 // We need platform devices to create symlinks. 182 if (!strncmp(uevent->subsystem, "platform", 8)) { 183 return COLDBOOT_CREATE; 184 } 185 186 // Ignores everything that is not a block device. 187 if (strncmp(uevent->subsystem, "block", 5)) { 188 return COLDBOOT_CONTINUE; 189 } 190 191 if (uevent->partition_name) { 192 // Matches partition name to create device nodes. 193 // Both required_devices_partition_names_ and uevent->partition_name have A/B 194 // suffix when A/B is used. 195 auto iter = required_devices_partition_names_.find(uevent->partition_name); 196 if (iter != required_devices_partition_names_.end()) { 197 LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter; 198 required_devices_partition_names_.erase(iter); 199 if (required_devices_partition_names_.empty()) { 200 return COLDBOOT_STOP; // Found all partitions, stop coldboot. 201 } else { 202 return COLDBOOT_CREATE; // Creates this device and continue to find others. 203 } 204 } 205 } 206 // Not found a partition or find an unneeded partition, continue to find others. 207 return COLDBOOT_CONTINUE; 208 } 209 210 // Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX. 211 void FirstStageMount::InitVerityDevice(const std::string& verity_device) { 212 const std::string device_name(basename(verity_device.c_str())); 213 const std::string syspath = "/sys/block/" + device_name; 214 215 device_init(syspath.c_str(), [&](uevent* uevent) -> coldboot_action_t { 216 if (uevent->device_name && uevent->device_name == device_name) { 217 LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; 218 return COLDBOOT_STOP; 219 } 220 return COLDBOOT_CONTINUE; 221 }); 222 device_close(); 223 } 224 225 bool FirstStageMount::MountPartitions() { 226 for (auto fstab_rec : mount_fstab_recs_) { 227 if (!SetUpDmVerity(fstab_rec)) { 228 PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'"; 229 return false; 230 } 231 if (fs_mgr_do_mount_one(fstab_rec)) { 232 PLOG(ERROR) << "Failed to mount '" << fstab_rec->mount_point << "'"; 233 return false; 234 } 235 } 236 return true; 237 } 238 239 bool FirstStageMountVBootV1::GetRequiredDevices() { 240 std::string verity_loc_device; 241 need_dm_verity_ = false; 242 243 for (auto fstab_rec : mount_fstab_recs_) { 244 // Don't allow verifyatboot in the first stage. 245 if (fs_mgr_is_verifyatboot(fstab_rec)) { 246 LOG(ERROR) << "Partitions can't be verified at boot"; 247 return false; 248 } 249 // Checks for verified partitions. 250 if (fs_mgr_is_verified(fstab_rec)) { 251 need_dm_verity_ = true; 252 } 253 // Checks if verity metadata is on a separate partition. Note that it is 254 // not partition specific, so there must be only one additional partition 255 // that carries verity state. 256 if (fstab_rec->verity_loc) { 257 if (verity_loc_device.empty()) { 258 verity_loc_device = fstab_rec->verity_loc; 259 } else if (verity_loc_device != fstab_rec->verity_loc) { 260 LOG(ERROR) << "More than one verity_loc found: " << verity_loc_device << ", " 261 << fstab_rec->verity_loc; 262 return false; 263 } 264 } 265 } 266 267 // Includes the partition names of fstab records and verity_loc_device (if any). 268 // Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used. 269 for (auto fstab_rec : mount_fstab_recs_) { 270 required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); 271 } 272 273 if (!verity_loc_device.empty()) { 274 required_devices_partition_names_.emplace(basename(verity_loc_device.c_str())); 275 } 276 277 return true; 278 } 279 280 bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { 281 if (fs_mgr_is_verified(fstab_rec)) { 282 int ret = fs_mgr_setup_verity(fstab_rec, false /* wait_for_verity_dev */); 283 if (ret == FS_MGR_SETUP_VERITY_DISABLED) { 284 LOG(INFO) << "Verity disabled for '" << fstab_rec->mount_point << "'"; 285 } else if (ret == FS_MGR_SETUP_VERITY_SUCCESS) { 286 // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". 287 // Needs to create it because ueventd isn't started in init first stage. 288 InitVerityDevice(fstab_rec->blk_device); 289 } else { 290 return false; 291 } 292 } 293 return true; // Returns true to mount the partition. 294 } 295 296 // FirstStageMountVBootV2 constructor. 297 // Gets the vbmeta partitions from device tree. 298 // /{ 299 // firmware { 300 // android { 301 // vbmeta { 302 // compatible = "android,vbmeta"; 303 // parts = "vbmeta,boot,system,vendor" 304 // }; 305 // }; 306 // }; 307 // } 308 FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) { 309 if (!read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts_)) { 310 PLOG(ERROR) << "Failed to read vbmeta/parts from device tree"; 311 return; 312 } 313 } 314 315 bool FirstStageMountVBootV2::GetRequiredDevices() { 316 need_dm_verity_ = false; 317 318 // fstab_rec->blk_device has A/B suffix. 319 for (auto fstab_rec : mount_fstab_recs_) { 320 if (fs_mgr_is_avb(fstab_rec)) { 321 need_dm_verity_ = true; 322 } 323 required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); 324 } 325 326 // libavb verifies AVB metadata on all verified partitions at once. 327 // e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor" 328 // for libavb to verify metadata, even if there is only /vendor in the 329 // above mount_fstab_recs_. 330 if (need_dm_verity_) { 331 if (device_tree_vbmeta_parts_.empty()) { 332 LOG(ERROR) << "Missing vbmeta parts in device tree"; 333 return false; 334 } 335 std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ","); 336 std::string ab_suffix = fs_mgr_get_slot_suffix(); 337 for (const auto& partition : partitions) { 338 // required_devices_partition_names_ is of type std::set so it's not an issue 339 // to emplace a partition twice. e.g., /vendor might be in both places: 340 // - device_tree_vbmeta_parts_ = "vbmeta,boot,system,vendor" 341 // - mount_fstab_recs_: /vendor_a 342 required_devices_partition_names_.emplace(partition + ab_suffix); 343 } 344 } 345 return true; 346 } 347 348 coldboot_action_t FirstStageMountVBootV2::ColdbootCallback(uevent* uevent) { 349 // Invokes the parent function to see if any desired partition has been found. 350 // If yes, record the by-name symlink for creating FsManagerAvbHandle later. 351 coldboot_action_t parent_callback_ret = FirstStageMount::ColdbootCallback(uevent); 352 353 // Skips the uevent if the parent function returns COLDBOOT_CONTINUE (meaning 354 // that the uevent was skipped) or there is no uevent->partition_name to 355 // create the by-name symlink. 356 if (parent_callback_ret != COLDBOOT_CONTINUE && uevent->partition_name) { 357 // get_block_device_symlinks() will return three symlinks at most, depending on 358 // the content of uevent. by-name symlink will be at [0] if uevent->partition_name 359 // is not empty. e.g., 360 // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem 361 // - /dev/block/platform/soc.0/f9824900.sdhci/by-num/p1 362 // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1 363 char** links = get_block_device_symlinks(uevent); 364 if (links && links[0]) { 365 auto[it, inserted] = by_name_symlink_map_.emplace(uevent->partition_name, links[0]); 366 if (!inserted) { 367 LOG(ERROR) << "Partition '" << uevent->partition_name 368 << "' already existed in the by-name symlink map with a value of '" 369 << it->second << "', new value '" << links[0] << "' will be ignored."; 370 } 371 } 372 } 373 374 return parent_callback_ret; 375 } 376 377 bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { 378 if (fs_mgr_is_avb(fstab_rec)) { 379 if (!InitAvbHandle()) return false; 380 if (avb_handle_->hashtree_disabled()) { 381 LOG(INFO) << "avb hashtree disabled for '" << fstab_rec->mount_point << "'"; 382 } else if (avb_handle_->SetUpAvb(fstab_rec, false /* wait_for_verity_dev */)) { 383 // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". 384 // Needs to create it because ueventd isn't started in init first stage. 385 InitVerityDevice(fstab_rec->blk_device); 386 } else { 387 return false; 388 } 389 } 390 return true; // Returns true to mount the partition. 391 } 392 393 bool FirstStageMountVBootV2::InitAvbHandle() { 394 if (avb_handle_) return true; // Returns true if the handle is already initialized. 395 396 if (by_name_symlink_map_.empty()) { 397 LOG(ERROR) << "by_name_symlink_map_ is empty"; 398 return false; 399 } 400 401 avb_handle_ = FsManagerAvbHandle::Open(std::move(by_name_symlink_map_)); 402 by_name_symlink_map_.clear(); // Removes all elements after the above std::move(). 403 404 if (!avb_handle_) { 405 PLOG(ERROR) << "Failed to open FsManagerAvbHandle"; 406 return false; 407 } 408 // Sets INIT_AVB_VERSION here for init to set ro.boot.avb_version in the second stage. 409 setenv("INIT_AVB_VERSION", avb_handle_->avb_version().c_str(), 1); 410 return true; 411 } 412 413 // Public functions 414 // ---------------- 415 // Mounts /system, /vendor, and/or /odm if they are present in the fstab provided by device tree. 416 bool DoFirstStageMount() { 417 // Skips first stage mount if we're in recovery mode. 418 if (IsRecoveryMode()) { 419 LOG(INFO) << "First stage mount skipped (recovery mode)"; 420 return true; 421 } 422 423 // Firstly checks if device tree fstab entries are compatible. 424 if (!is_android_dt_value_expected("fstab/compatible", "android,fstab")) { 425 LOG(INFO) << "First stage mount skipped (missing/incompatible fstab in device tree)"; 426 return true; 427 } 428 429 std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create(); 430 if (!handle) { 431 LOG(ERROR) << "Failed to create FirstStageMount"; 432 return false; 433 } 434 return handle->DoFirstStageMount(); 435 } 436 437 void SetInitAvbVersionInRecovery() { 438 if (!IsRecoveryMode()) { 439 LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not in recovery mode)"; 440 return; 441 } 442 443 if (!IsDtVbmetaCompatible()) { 444 LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)"; 445 return; 446 } 447 448 // Initializes required devices for the subsequent FsManagerAvbHandle::Open() 449 // to verify AVB metadata on all partitions in the verified chain. 450 // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the 451 // Open() function returns a valid handle. 452 // We don't need to mount partitions here in recovery mode. 453 FirstStageMountVBootV2 avb_first_mount; 454 if (!avb_first_mount.InitDevices()) { 455 LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION"; 456 return; 457 } 458 459 FsManagerAvbUniquePtr avb_handle = 460 FsManagerAvbHandle::Open(std::move(avb_first_mount.by_name_symlink_map_)); 461 if (!avb_handle) { 462 PLOG(ERROR) << "Failed to open FsManagerAvbHandle for INIT_AVB_VERSION"; 463 return; 464 } 465 setenv("INIT_AVB_VERSION", avb_handle->avb_version().c_str(), 1); 466 } 467