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