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