1 /* 2 * Copyright (C) 2015 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 <endian.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <string.h> 21 22 #include <string> 23 24 #include <android-base/file.h> 25 #include <android-base/logging.h> 26 #include <android-base/properties.h> 27 #include <android-base/stringprintf.h> 28 #include <android-base/unique_fd.h> 29 #include <hardware/boot_control.h> 30 #include <hardware/hardware.h> 31 32 #include <bootloader_message/bootloader_message.h> 33 34 struct boot_control_private_t { 35 // The base struct needs to be first in the list. 36 boot_control_module_t base; 37 38 // Whether this struct was initialized with data from the bootloader message 39 // that doesn't change until next reboot. 40 bool initialized; 41 42 // The path to the misc_device as reported in the fstab. 43 const char* misc_device; 44 45 // The number of slots present on the device. 46 unsigned int num_slots; 47 48 // The slot where we are running from. 49 unsigned int current_slot; 50 }; 51 52 namespace { 53 54 // The number of boot attempts that should be made from a new slot before 55 // rolling back to the previous slot. 56 constexpr unsigned int kDefaultBootAttempts = 7; 57 static_assert(kDefaultBootAttempts < 8, "tries_remaining field only has 3 bits"); 58 59 constexpr unsigned int kMaxNumSlots = 60 sizeof(bootloader_control::slot_info) / sizeof(bootloader_control::slot_info[0]); 61 constexpr const char* kSlotSuffixes[kMaxNumSlots] = { "_a", "_b", "_c", "_d" }; 62 constexpr off_t kBootloaderControlOffset = offsetof(bootloader_message_ab, slot_suffix); 63 64 static uint32_t CRC32(const uint8_t* buf, size_t size) { 65 static uint32_t crc_table[256]; 66 67 // Compute the CRC-32 table only once. 68 if (!crc_table[1]) { 69 for (uint32_t i = 0; i < 256; ++i) { 70 uint32_t crc = i; 71 for (uint32_t j = 0; j < 8; ++j) { 72 uint32_t mask = -(crc & 1); 73 crc = (crc >> 1) ^ (0xEDB88320 & mask); 74 } 75 crc_table[i] = crc; 76 } 77 } 78 79 uint32_t ret = -1; 80 for (size_t i = 0; i < size; ++i) { 81 ret = (ret >> 8) ^ crc_table[(ret ^ buf[i]) & 0xFF]; 82 } 83 84 return ~ret; 85 } 86 87 // Return the little-endian representation of the CRC-32 of the first fields 88 // in |boot_ctrl| up to the crc32_le field. 89 uint32_t BootloaderControlLECRC(const bootloader_control* boot_ctrl) { 90 return htole32( 91 CRC32(reinterpret_cast<const uint8_t*>(boot_ctrl), offsetof(bootloader_control, crc32_le))); 92 } 93 94 bool LoadBootloaderControl(const char* misc_device, bootloader_control* buffer) { 95 android::base::unique_fd fd(open(misc_device, O_RDONLY)); 96 if (fd.get() == -1) { 97 PLOG(ERROR) << "failed to open " << misc_device; 98 return false; 99 } 100 if (lseek(fd, kBootloaderControlOffset, SEEK_SET) != kBootloaderControlOffset) { 101 PLOG(ERROR) << "failed to lseek " << misc_device; 102 return false; 103 } 104 if (!android::base::ReadFully(fd.get(), buffer, sizeof(bootloader_control))) { 105 PLOG(ERROR) << "failed to read " << misc_device; 106 return false; 107 } 108 return true; 109 } 110 111 bool UpdateAndSaveBootloaderControl(const char* misc_device, bootloader_control* buffer) { 112 buffer->crc32_le = BootloaderControlLECRC(buffer); 113 android::base::unique_fd fd(open(misc_device, O_WRONLY | O_SYNC)); 114 if (fd.get() == -1) { 115 PLOG(ERROR) << "failed to open " << misc_device; 116 return false; 117 } 118 if (lseek(fd.get(), kBootloaderControlOffset, SEEK_SET) != kBootloaderControlOffset) { 119 PLOG(ERROR) << "failed to lseek " << misc_device; 120 return false; 121 } 122 if (!android::base::WriteFully(fd.get(), buffer, sizeof(bootloader_control))) { 123 PLOG(ERROR) << "failed to write " << misc_device; 124 return false; 125 } 126 return true; 127 } 128 129 void InitDefaultBootloaderControl(const boot_control_private_t* module, 130 bootloader_control* boot_ctrl) { 131 memset(boot_ctrl, 0, sizeof(*boot_ctrl)); 132 133 if (module->current_slot < kMaxNumSlots) { 134 strlcpy(boot_ctrl->slot_suffix, kSlotSuffixes[module->current_slot], 135 sizeof(boot_ctrl->slot_suffix)); 136 } 137 boot_ctrl->magic = BOOT_CTRL_MAGIC; 138 boot_ctrl->version = BOOT_CTRL_VERSION; 139 140 // Figure out the number of slots by checking if the partitions exist, 141 // otherwise assume the maximum supported by the header. 142 boot_ctrl->nb_slot = kMaxNumSlots; 143 std::string base_path = module->misc_device; 144 size_t last_path_sep = base_path.rfind('/'); 145 if (last_path_sep != std::string::npos) { 146 // We test the existence of the "boot" partition on each possible slot, 147 // which is a partition required by Android Bootloader Requirements. 148 base_path = base_path.substr(0, last_path_sep + 1) + "boot"; 149 int last_existing_slot = -1; 150 int first_missing_slot = -1; 151 for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) { 152 std::string partition_path = base_path + kSlotSuffixes[slot]; 153 struct stat part_stat; 154 int err = stat(partition_path.c_str(), &part_stat); 155 if (!err) { 156 last_existing_slot = slot; 157 LOG(INFO) << "Found slot: " << kSlotSuffixes[slot]; 158 } else if (err < 0 && errno == ENOENT && first_missing_slot == -1) { 159 first_missing_slot = slot; 160 } 161 } 162 // We only declare that we found the actual number of slots if we found all 163 // the boot partitions up to the number of slots, and no boot partition 164 // after that. Not finding any of the boot partitions implies a problem so 165 // we just leave the number of slots in the maximum value. 166 if ((last_existing_slot != -1 && last_existing_slot + 1 == first_missing_slot) || 167 (first_missing_slot == -1 && last_existing_slot + 1 == kMaxNumSlots)) { 168 boot_ctrl->nb_slot = last_existing_slot + 1; 169 LOG(INFO) << "Found a system with " << last_existing_slot + 1 << " slots."; 170 } 171 } 172 173 for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) { 174 slot_metadata entry = {}; 175 176 if (slot < boot_ctrl->nb_slot) { 177 entry.priority = 7; 178 entry.tries_remaining = kDefaultBootAttempts; 179 entry.successful_boot = 0; 180 } else { 181 entry.priority = 0; // Unbootable 182 } 183 184 // When the boot_control stored on disk is invalid, we assume that the 185 // current slot is successful. The bootloader should repair this situation 186 // before booting and write a valid boot_control slot, so if we reach this 187 // stage it means that the misc partition was corrupted since boot. 188 if (module->current_slot == slot) { 189 entry.successful_boot = 1; 190 } 191 192 boot_ctrl->slot_info[slot] = entry; 193 } 194 boot_ctrl->recovery_tries_remaining = 0; 195 196 boot_ctrl->crc32_le = BootloaderControlLECRC(boot_ctrl); 197 } 198 199 // Return the index of the slot suffix passed or -1 if not a valid slot suffix. 200 int SlotSuffixToIndex(const char* suffix) { 201 for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) { 202 if (!strcmp(kSlotSuffixes[slot], suffix)) return slot; 203 } 204 return -1; 205 } 206 207 // Initialize the boot_control_private struct with the information from 208 // the bootloader_message buffer stored in |boot_ctrl|. Returns whether the 209 // initialization succeeded. 210 bool BootControl_lazyInitialization(boot_control_private_t* module) { 211 if (module->initialized) return true; 212 213 // Initialize the current_slot from the read-only property. If the property 214 // was not set (from either the command line or the device tree), we can later 215 // initialize it from the bootloader_control struct. 216 std::string suffix_prop = android::base::GetProperty("ro.boot.slot_suffix", ""); 217 module->current_slot = SlotSuffixToIndex(suffix_prop.c_str()); 218 219 std::string err; 220 std::string device = get_bootloader_message_blk_device(&err); 221 if (device.empty()) return false; 222 223 bootloader_control boot_ctrl; 224 if (!LoadBootloaderControl(device.c_str(), &boot_ctrl)) return false; 225 226 // Note that since there isn't a module unload function this memory is leaked. 227 module->misc_device = strdup(device.c_str()); 228 module->initialized = true; 229 230 // Validate the loaded data, otherwise we will destroy it and re-initialize it 231 // with the current information. 232 uint32_t computed_crc32 = BootloaderControlLECRC(&boot_ctrl); 233 if (boot_ctrl.crc32_le != computed_crc32) { 234 LOG(WARNING) << "Invalid boot control found, expected CRC-32 0x" << std::hex << computed_crc32 235 << " but found 0x" << std::hex << boot_ctrl.crc32_le << ". Re-initializing."; 236 InitDefaultBootloaderControl(module, &boot_ctrl); 237 UpdateAndSaveBootloaderControl(device.c_str(), &boot_ctrl); 238 } 239 240 module->num_slots = boot_ctrl.nb_slot; 241 return true; 242 } 243 244 void BootControl_init(boot_control_module_t* module) { 245 BootControl_lazyInitialization(reinterpret_cast<boot_control_private_t*>(module)); 246 } 247 248 unsigned int BootControl_getNumberSlots(boot_control_module_t* module) { 249 return reinterpret_cast<boot_control_private_t*>(module)->num_slots; 250 } 251 252 unsigned int BootControl_getCurrentSlot(boot_control_module_t* module) { 253 return reinterpret_cast<boot_control_private_t*>(module)->current_slot; 254 } 255 256 int BootControl_markBootSuccessful(boot_control_module_t* module) { 257 boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module); 258 259 bootloader_control bootctrl; 260 if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 261 262 bootctrl.slot_info[bootctrl_module->current_slot].successful_boot = 1; 263 // tries_remaining == 0 means that the slot is not bootable anymore, make 264 // sure we mark the current slot as bootable if it succeeds in the last 265 // attempt. 266 bootctrl.slot_info[bootctrl_module->current_slot].tries_remaining = 1; 267 if (!UpdateAndSaveBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 268 return 0; 269 } 270 271 int BootControl_setActiveBootSlot(boot_control_module_t* module, unsigned int slot) { 272 boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module); 273 274 if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) { 275 // Invalid slot number. 276 return -1; 277 } 278 279 bootloader_control bootctrl; 280 if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 281 282 // Set every other slot with a lower priority than the new "active" slot. 283 const unsigned int kActivePriority = 15; 284 const unsigned int kActiveTries = 6; 285 for (unsigned int i = 0; i < bootctrl_module->num_slots; ++i) { 286 if (i != slot) { 287 if (bootctrl.slot_info[i].priority >= kActivePriority) 288 bootctrl.slot_info[i].priority = kActivePriority - 1; 289 } 290 } 291 292 // Note that setting a slot as active doesn't change the successful bit. 293 // The successful bit will only be changed by setSlotAsUnbootable(). 294 bootctrl.slot_info[slot].priority = kActivePriority; 295 bootctrl.slot_info[slot].tries_remaining = kActiveTries; 296 297 // Setting the current slot as active is a way to revert the operation that 298 // set *another* slot as active at the end of an updater. This is commonly 299 // used to cancel the pending update. We should only reset the verity_corrpted 300 // bit when attempting a new slot, otherwise the verity bit on the current 301 // slot would be flip. 302 if (slot != bootctrl_module->current_slot) bootctrl.slot_info[slot].verity_corrupted = 0; 303 304 if (!UpdateAndSaveBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 305 return 0; 306 } 307 308 int BootControl_setSlotAsUnbootable(struct boot_control_module* module, unsigned int slot) { 309 boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module); 310 311 if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) { 312 // Invalid slot number. 313 return -1; 314 } 315 316 bootloader_control bootctrl; 317 if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 318 319 // The only way to mark a slot as unbootable, regardless of the priority is to 320 // set the tries_remaining to 0. 321 bootctrl.slot_info[slot].successful_boot = 0; 322 bootctrl.slot_info[slot].tries_remaining = 0; 323 if (!UpdateAndSaveBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 324 return 0; 325 } 326 327 int BootControl_isSlotBootable(struct boot_control_module* module, unsigned int slot) { 328 boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module); 329 330 if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) { 331 // Invalid slot number. 332 return -1; 333 } 334 335 bootloader_control bootctrl; 336 if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 337 338 return bootctrl.slot_info[slot].tries_remaining; 339 } 340 341 int BootControl_isSlotMarkedSuccessful(struct boot_control_module* module, unsigned int slot) { 342 boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module); 343 344 if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) { 345 // Invalid slot number. 346 return -1; 347 } 348 349 bootloader_control bootctrl; 350 if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1; 351 352 return bootctrl.slot_info[slot].successful_boot && bootctrl.slot_info[slot].tries_remaining; 353 } 354 355 const char* BootControl_getSuffix(boot_control_module_t* module, unsigned int slot) { 356 if (slot >= kMaxNumSlots || slot >= reinterpret_cast<boot_control_private_t*>(module)->num_slots) { 357 return NULL; 358 } 359 return kSlotSuffixes[slot]; 360 } 361 362 static int BootControl_open(const hw_module_t* module __unused, const char* id __unused, 363 hw_device_t** device __unused) { 364 /* Nothing to do currently. */ 365 return 0; 366 } 367 368 struct hw_module_methods_t BootControl_methods = { 369 .open = BootControl_open, 370 }; 371 372 } // namespace 373 374 boot_control_private_t HAL_MODULE_INFO_SYM = { 375 .base = 376 { 377 .common = 378 { 379 .tag = HARDWARE_MODULE_TAG, 380 .module_api_version = BOOT_CONTROL_MODULE_API_VERSION_0_1, 381 .hal_api_version = HARDWARE_HAL_API_VERSION, 382 .id = BOOT_CONTROL_HARDWARE_MODULE_ID, 383 .name = "AOSP reference bootctrl HAL", 384 .author = "The Android Open Source Project", 385 .methods = &BootControl_methods, 386 }, 387 .init = BootControl_init, 388 .getNumberSlots = BootControl_getNumberSlots, 389 .getCurrentSlot = BootControl_getCurrentSlot, 390 .markBootSuccessful = BootControl_markBootSuccessful, 391 .setActiveBootSlot = BootControl_setActiveBootSlot, 392 .setSlotAsUnbootable = BootControl_setSlotAsUnbootable, 393 .isSlotBootable = BootControl_isSlotBootable, 394 .getSuffix = BootControl_getSuffix, 395 .isSlotMarkedSuccessful = BootControl_isSlotMarkedSuccessful, 396 }, 397 .initialized = false, 398 .misc_device = nullptr, 399 .num_slots = 0, 400 .current_slot = 0, 401 }; 402