1// SPDX-License-Identifier: BSD-2-Clause 2/* 3 * Copyright (C) 2017 The Android Open Source Project 4 */ 5#include <common.h> 6#include <android_ab.h> 7#include <android_bootloader_message.h> 8#include <blk.h> 9#include <log.h> 10#include <malloc.h> 11#include <part.h> 12#include <memalign.h> 13#include <linux/err.h> 14#include <u-boot/crc.h> 15 16/** 17 * Compute the CRC-32 of the bootloader control struct. 18 * 19 * Only the bytes up to the crc32_le field are considered for the CRC-32 20 * calculation. 21 * 22 * @param[in] abc bootloader control block 23 * 24 * Return: crc32 sum 25 */ 26static uint32_t ab_control_compute_crc(struct bootloader_control *abc) 27{ 28 return crc32(0, (void *)abc, offsetof(typeof(*abc), crc32_le)); 29} 30 31/** 32 * Initialize bootloader_control to the default value. 33 * 34 * It allows us to boot all slots in order from the first one. This value 35 * should be used when the bootloader message is corrupted, but not when 36 * a valid message indicates that all slots are unbootable. 37 * 38 * @param[in] abc bootloader control block 39 * 40 * Return: 0 on success and a negative on error 41 */ 42static int ab_control_default(struct bootloader_control *abc) 43{ 44 int i; 45 const struct slot_metadata metadata = { 46 .priority = 15, 47 .tries_remaining = 7, 48 .successful_boot = 0, 49 .verity_corrupted = 0, 50 .reserved = 0 51 }; 52 53 if (!abc) 54 return -EFAULT; 55 56 memcpy(abc->slot_suffix, "a\0\0\0", 4); 57 abc->magic = BOOT_CTRL_MAGIC; 58 abc->version = BOOT_CTRL_VERSION; 59 abc->nb_slot = NUM_SLOTS; 60 memset(abc->reserved0, 0, sizeof(abc->reserved0)); 61 for (i = 0; i < abc->nb_slot; ++i) 62 abc->slot_info[i] = metadata; 63 64 memset(abc->reserved1, 0, sizeof(abc->reserved1)); 65 abc->crc32_le = ab_control_compute_crc(abc); 66 67 return 0; 68} 69 70/** 71 * Load the boot_control struct from disk into newly allocated memory. 72 * 73 * This function allocates and returns an integer number of disk blocks, 74 * based on the block size of the passed device to help performing a 75 * read-modify-write operation on the boot_control struct. 76 * The boot_control struct offset (2 KiB) must be a multiple of the device 77 * block size, for simplicity. 78 * 79 * @param[in] dev_desc Device where to read the boot_control struct from 80 * @param[in] part_info Partition in 'dev_desc' where to read from, normally 81 * the "misc" partition should be used 82 * @param[out] pointer to pointer to bootloader_control data 83 * Return: 0 on success and a negative on error 84 */ 85static int ab_control_create_from_disk(struct blk_desc *dev_desc, 86 const struct disk_partition *part_info, 87 struct bootloader_control **abc, 88 ulong offset) 89{ 90 ulong abc_offset, abc_blocks, ret; 91 92 abc_offset = offset + 93 offsetof(struct bootloader_message_ab, slot_suffix); 94 if (abc_offset % part_info->blksz) { 95 log_err("ANDROID: Boot control block not block aligned.\n"); 96 return -EINVAL; 97 } 98 abc_offset /= part_info->blksz; 99 100 abc_blocks = DIV_ROUND_UP(sizeof(struct bootloader_control), 101 part_info->blksz); 102 if (abc_offset + abc_blocks > part_info->size) { 103 log_err("ANDROID: boot control partition too small. Need at"); 104 log_err(" least %lu blocks but have %lu blocks.\n", 105 abc_offset + abc_blocks, part_info->size); 106 return -EINVAL; 107 } 108 *abc = malloc_cache_aligned(abc_blocks * part_info->blksz); 109 if (!*abc) 110 return -ENOMEM; 111 112 ret = blk_dread(dev_desc, part_info->start + abc_offset, abc_blocks, 113 *abc); 114 if (IS_ERR_VALUE(ret)) { 115 log_err("ANDROID: Could not read from boot ctrl partition\n"); 116 free(*abc); 117 return -EIO; 118 } 119 120 log_debug("ANDROID: Loaded ABC, %lu blocks\n", abc_blocks); 121 122 return 0; 123} 124 125/** 126 * Store the loaded boot_control block. 127 * 128 * Store back to the same location it was read from with 129 * ab_control_create_from_misc(). 130 * 131 * @param[in] dev_desc Device where we should write the boot_control struct 132 * @param[in] part_info Partition on the 'dev_desc' where to write 133 * @param[in] abc Pointer to the boot control struct and the extra bytes after 134 * it up to the nearest block boundary 135 * Return: 0 on success and a negative on error 136 */ 137static int ab_control_store(struct blk_desc *dev_desc, 138 const struct disk_partition *part_info, 139 struct bootloader_control *abc, ulong offset) 140{ 141 ulong abc_offset, abc_blocks, ret; 142 143 abc_offset = offset + 144 offsetof(struct bootloader_message_ab, slot_suffix) / 145 part_info->blksz; 146 abc_blocks = DIV_ROUND_UP(sizeof(struct bootloader_control), 147 part_info->blksz); 148 ret = blk_dwrite(dev_desc, part_info->start + abc_offset, abc_blocks, 149 abc); 150 if (IS_ERR_VALUE(ret)) { 151 log_err("ANDROID: Could not write back the misc partition\n"); 152 return -EIO; 153 } 154 155 return 0; 156} 157 158/** 159 * Compare two slots. 160 * 161 * The function determines slot which is should we boot from among the two. 162 * 163 * @param[in] a The first bootable slot metadata 164 * @param[in] b The second bootable slot metadata 165 * Return: Negative if the slot "a" is better, positive of the slot "b" is 166 * better or 0 if they are equally good. 167 */ 168static int ab_compare_slots(const struct slot_metadata *a, 169 const struct slot_metadata *b) 170{ 171 /* Higher priority is better */ 172 if (a->priority != b->priority) 173 return b->priority - a->priority; 174 175 /* Higher successful_boot value is better, in case of same priority */ 176 if (a->successful_boot != b->successful_boot) 177 return b->successful_boot - a->successful_boot; 178 179 /* Higher tries_remaining is better to ensure round-robin */ 180 if (a->tries_remaining != b->tries_remaining) 181 return b->tries_remaining - a->tries_remaining; 182 183 return 0; 184} 185 186int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info, 187 bool dec_tries) 188{ 189 struct bootloader_control *abc = NULL; 190 struct bootloader_control *backup_abc = NULL; 191 u32 crc32_le; 192 int slot, i, ret; 193 bool store_needed = false; 194 bool valid_backup = false; 195 char slot_suffix[4]; 196 197 ret = ab_control_create_from_disk(dev_desc, part_info, &abc, 0); 198 if (ret < 0) { 199 /* 200 * This condition represents an actual problem with the code or 201 * the board setup, like an invalid partition information. 202 * Signal a repair mode and do not try to boot from either slot. 203 */ 204 return ret; 205 } 206 207 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) { 208 ret = ab_control_create_from_disk(dev_desc, part_info, &backup_abc, 209 CONFIG_ANDROID_AB_BACKUP_OFFSET); 210 if (ret < 0) { 211 free(abc); 212 return ret; 213 } 214 } 215 216 crc32_le = ab_control_compute_crc(abc); 217 if (abc->crc32_le != crc32_le) { 218 log_err("ANDROID: Invalid CRC-32 (expected %.8x, found %.8x),", 219 crc32_le, abc->crc32_le); 220 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) { 221 crc32_le = ab_control_compute_crc(backup_abc); 222 if (backup_abc->crc32_le != crc32_le) { 223 log_err(" ANDROID: Invalid backup CRC-32 "); 224 log_err("(expected %.8x, found %.8x),", 225 crc32_le, backup_abc->crc32_le); 226 } else { 227 valid_backup = true; 228 log_info(" copying A/B metadata from backup.\n"); 229 memcpy(abc, backup_abc, sizeof(*abc)); 230 } 231 } 232 233 if (!valid_backup) { 234 log_err(" re-initializing A/B metadata.\n"); 235 ret = ab_control_default(abc); 236 if (ret < 0) { 237 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) 238 free(backup_abc); 239 free(abc); 240 return -ENODATA; 241 } 242 } 243 store_needed = true; 244 } 245 246 if (abc->magic != BOOT_CTRL_MAGIC) { 247 log_err("ANDROID: Unknown A/B metadata: %.8x\n", abc->magic); 248 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) 249 free(backup_abc); 250 free(abc); 251 return -ENODATA; 252 } 253 254 if (abc->version > BOOT_CTRL_VERSION) { 255 log_err("ANDROID: Unsupported A/B metadata version: %.8x\n", 256 abc->version); 257 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) 258 free(backup_abc); 259 free(abc); 260 return -ENODATA; 261 } 262 263 /* 264 * At this point a valid boot control metadata is stored in abc, 265 * followed by other reserved data in the same block. We select a with 266 * the higher priority slot that 267 * - is not marked as corrupted and 268 * - either has tries_remaining > 0 or successful_boot is true. 269 * If the selected slot has a false successful_boot, we also decrement 270 * the tries_remaining until it eventually becomes unbootable because 271 * tries_remaining reaches 0. This mechanism produces a bootloader 272 * induced rollback, typically right after a failed update. 273 */ 274 275 /* Safety check: limit the number of slots. */ 276 if (abc->nb_slot > ARRAY_SIZE(abc->slot_info)) { 277 abc->nb_slot = ARRAY_SIZE(abc->slot_info); 278 store_needed = true; 279 } 280 281 slot = -1; 282 for (i = 0; i < abc->nb_slot; ++i) { 283 if (abc->slot_info[i].verity_corrupted || 284 !abc->slot_info[i].tries_remaining) { 285 log_debug("ANDROID: unbootable slot %d tries: %d, ", 286 i, abc->slot_info[i].tries_remaining); 287 log_debug("corrupt: %d\n", 288 abc->slot_info[i].verity_corrupted); 289 continue; 290 } 291 log_debug("ANDROID: bootable slot %d pri: %d, tries: %d, ", 292 i, abc->slot_info[i].priority, 293 abc->slot_info[i].tries_remaining); 294 log_debug("corrupt: %d, successful: %d\n", 295 abc->slot_info[i].verity_corrupted, 296 abc->slot_info[i].successful_boot); 297 298 if (slot < 0 || 299 ab_compare_slots(&abc->slot_info[i], 300 &abc->slot_info[slot]) < 0) { 301 slot = i; 302 } 303 } 304 305 if (slot >= 0 && !abc->slot_info[slot].successful_boot) { 306 log_err("ANDROID: Attempting slot %c, tries remaining %d\n", 307 BOOT_SLOT_NAME(slot), 308 abc->slot_info[slot].tries_remaining); 309 if (dec_tries) { 310 abc->slot_info[slot].tries_remaining--; 311 store_needed = true; 312 } 313 } 314 315 if (slot >= 0) { 316 /* 317 * Legacy user-space requires this field to be set in the BCB. 318 * Newer releases load this slot suffix from the command line 319 * or the device tree. 320 */ 321 memset(slot_suffix, 0, sizeof(slot_suffix)); 322 slot_suffix[0] = BOOT_SLOT_NAME(slot); 323 if (memcmp(abc->slot_suffix, slot_suffix, 324 sizeof(slot_suffix))) { 325 memcpy(abc->slot_suffix, slot_suffix, 326 sizeof(slot_suffix)); 327 store_needed = true; 328 } 329 } 330 331 if (store_needed) { 332 abc->crc32_le = ab_control_compute_crc(abc); 333 ret = ab_control_store(dev_desc, part_info, abc, 0); 334 if (ret < 0) { 335 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) 336 free(backup_abc); 337 free(abc); 338 return ret; 339 } 340 } 341 342 if (CONFIG_ANDROID_AB_BACKUP_OFFSET) { 343 /* 344 * If the backup doesn't match the primary, write the primary 345 * to the backup offset 346 */ 347 if (memcmp(backup_abc, abc, sizeof(*abc)) != 0) { 348 ret = ab_control_store(dev_desc, part_info, abc, 349 CONFIG_ANDROID_AB_BACKUP_OFFSET); 350 if (ret < 0) { 351 free(backup_abc); 352 free(abc); 353 return ret; 354 } 355 } 356 free(backup_abc); 357 } 358 359 free(abc); 360 361 if (slot < 0) 362 return -EINVAL; 363 364 return slot; 365} 366