avb_ab_flow.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Permission is hereby granted, free of charge, to any person
  5. * obtaining a copy of this software and associated documentation
  6. * files (the "Software"), to deal in the Software without
  7. * restriction, including without limitation the rights to use, copy,
  8. * modify, merge, publish, distribute, sublicense, and/or sell copies
  9. * of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE.
  23. */
  24. #include "avb_ab_flow.h"
  25. bool avb_ab_data_verify_and_byteswap(const AvbABData* src, AvbABData* dest) {
  26. /* Ensure magic is correct. */
  27. if (avb_safe_memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
  28. avb_error("Magic is incorrect.\n");
  29. return false;
  30. }
  31. avb_memcpy(dest, src, sizeof(AvbABData));
  32. dest->crc32 = avb_be32toh(dest->crc32);
  33. /* Ensure we don't attempt to access any fields if the major version
  34. * is not supported.
  35. */
  36. if (dest->version_major > AVB_AB_MAJOR_VERSION) {
  37. avb_error("No support for given major version.\n");
  38. return false;
  39. }
  40. /* Bail if CRC32 doesn't match. */
  41. if (dest->crc32 !=
  42. avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) {
  43. avb_error("CRC32 does not match.\n");
  44. return false;
  45. }
  46. return true;
  47. }
  48. void avb_ab_data_update_crc_and_byteswap(const AvbABData* src,
  49. AvbABData* dest) {
  50. avb_memcpy(dest, src, sizeof(AvbABData));
  51. dest->crc32 = avb_htobe32(
  52. avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t)));
  53. }
  54. void avb_ab_data_init(AvbABData* data) {
  55. avb_memset(data, '\0', sizeof(AvbABData));
  56. avb_memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
  57. data->version_major = AVB_AB_MAJOR_VERSION;
  58. data->version_minor = AVB_AB_MINOR_VERSION;
  59. data->slots[0].priority = AVB_AB_MAX_PRIORITY;
  60. data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  61. data->slots[0].successful_boot = 0;
  62. data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1;
  63. data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  64. data->slots[1].successful_boot = 0;
  65. }
  66. /* The AvbABData struct is stored 2048 bytes into the 'misc' partition
  67. * following the 'struct bootloader_message' field. The struct is
  68. * compatible with the guidelines in bootable/recovery/bootloader.h -
  69. * e.g. it is stored in the |slot_suffix| field, starts with a
  70. * NUL-byte, and is 32 bytes long.
  71. */
  72. #define AB_METADATA_MISC_PARTITION_OFFSET 2048
  73. AvbIOResult avb_ab_data_read(AvbABOps* ab_ops, AvbABData* data) {
  74. AvbOps* ops = ab_ops->ops;
  75. AvbABData serialized;
  76. AvbIOResult io_ret;
  77. size_t num_bytes_read;
  78. io_ret = ops->read_from_partition(ops,
  79. "misc",
  80. AB_METADATA_MISC_PARTITION_OFFSET,
  81. sizeof(AvbABData),
  82. &serialized,
  83. &num_bytes_read);
  84. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  85. return AVB_IO_RESULT_ERROR_OOM;
  86. } else if (io_ret != AVB_IO_RESULT_OK ||
  87. num_bytes_read != sizeof(AvbABData)) {
  88. avb_error("Error reading A/B metadata.\n");
  89. return AVB_IO_RESULT_ERROR_IO;
  90. }
  91. if (!avb_ab_data_verify_and_byteswap(&serialized, data)) {
  92. avb_error(
  93. "Error validating A/B metadata from disk. "
  94. "Resetting and writing new A/B metadata to disk.\n");
  95. avb_ab_data_init(data);
  96. return avb_ab_data_write(ab_ops, data);
  97. }
  98. return AVB_IO_RESULT_OK;
  99. }
  100. AvbIOResult avb_ab_data_write(AvbABOps* ab_ops, const AvbABData* data) {
  101. AvbOps* ops = ab_ops->ops;
  102. AvbABData serialized;
  103. AvbIOResult io_ret;
  104. avb_ab_data_update_crc_and_byteswap(data, &serialized);
  105. io_ret = ops->write_to_partition(ops,
  106. "misc",
  107. AB_METADATA_MISC_PARTITION_OFFSET,
  108. sizeof(AvbABData),
  109. &serialized);
  110. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  111. return AVB_IO_RESULT_ERROR_OOM;
  112. } else if (io_ret != AVB_IO_RESULT_OK) {
  113. avb_error("Error writing A/B metadata.\n");
  114. return AVB_IO_RESULT_ERROR_IO;
  115. }
  116. return AVB_IO_RESULT_OK;
  117. }
  118. static bool slot_is_bootable(AvbABSlotData* slot) {
  119. return slot->priority > 0 &&
  120. (slot->successful_boot || (slot->tries_remaining > 0));
  121. }
  122. static void slot_set_unbootable(AvbABSlotData* slot) {
  123. slot->priority = 0;
  124. slot->tries_remaining = 0;
  125. slot->successful_boot = 0;
  126. }
  127. /* Ensure all unbootable and/or illegal states are marked as the
  128. * canonical 'unbootable' state, e.g. priority=0, tries_remaining=0,
  129. * and successful_boot=0.
  130. */
  131. static void slot_normalize(AvbABSlotData* slot) {
  132. if (slot->priority > 0) {
  133. if (slot->tries_remaining == 0 && !slot->successful_boot) {
  134. /* We've exhausted all tries -> unbootable. */
  135. slot_set_unbootable(slot);
  136. }
  137. if (slot->tries_remaining > 0 && slot->successful_boot) {
  138. /* Illegal state - avb_ab_mark_slot_successful() will clear
  139. * tries_remaining when setting successful_boot.
  140. */
  141. slot_set_unbootable(slot);
  142. }
  143. } else {
  144. slot_set_unbootable(slot);
  145. }
  146. }
  147. static const char* slot_suffixes[2] = {"_a", "_b"};
  148. /* Helper function to load metadata - returns AVB_IO_RESULT_OK on
  149. * success, error code otherwise.
  150. */
  151. static AvbIOResult load_metadata(AvbABOps* ab_ops,
  152. AvbABData* ab_data,
  153. AvbABData* ab_data_orig) {
  154. AvbIOResult io_ret;
  155. io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
  156. if (io_ret != AVB_IO_RESULT_OK) {
  157. avb_error("I/O error while loading A/B metadata.\n");
  158. return io_ret;
  159. }
  160. *ab_data_orig = *ab_data;
  161. /* Ensure data is normalized, e.g. illegal states will be marked as
  162. * unbootable and all unbootable states are represented with
  163. * (priority=0, tries_remaining=0, successful_boot=0).
  164. */
  165. slot_normalize(&ab_data->slots[0]);
  166. slot_normalize(&ab_data->slots[1]);
  167. return AVB_IO_RESULT_OK;
  168. }
  169. /* Writes A/B metadata to disk only if it has changed - returns
  170. * AVB_IO_RESULT_OK on success, error code otherwise.
  171. */
  172. static AvbIOResult save_metadata_if_changed(AvbABOps* ab_ops,
  173. AvbABData* ab_data,
  174. AvbABData* ab_data_orig) {
  175. if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
  176. avb_debug("Writing A/B metadata to disk.\n");
  177. return ab_ops->write_ab_metadata(ab_ops, ab_data);
  178. }
  179. return AVB_IO_RESULT_OK;
  180. }
  181. AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
  182. const char* const* requested_partitions,
  183. AvbSlotVerifyFlags flags,
  184. AvbHashtreeErrorMode hashtree_error_mode,
  185. AvbSlotVerifyData** out_data) {
  186. AvbOps* ops = ab_ops->ops;
  187. AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
  188. AvbSlotVerifyData* data = NULL;
  189. AvbABFlowResult ret;
  190. AvbABData ab_data, ab_data_orig;
  191. size_t slot_index_to_boot, n;
  192. AvbIOResult io_ret;
  193. bool saw_and_allowed_verification_error = false;
  194. io_ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  195. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  196. ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
  197. goto out;
  198. } else if (io_ret != AVB_IO_RESULT_OK) {
  199. ret = AVB_AB_FLOW_RESULT_ERROR_IO;
  200. goto out;
  201. }
  202. /* Validate all bootable slots. */
  203. for (n = 0; n < 2; n++) {
  204. if (slot_is_bootable(&ab_data.slots[n])) {
  205. AvbSlotVerifyResult verify_result;
  206. bool set_slot_unbootable = false;
  207. verify_result = avb_slot_verify(ops,
  208. requested_partitions,
  209. slot_suffixes[n],
  210. flags,
  211. hashtree_error_mode,
  212. &slot_data[n]);
  213. switch (verify_result) {
  214. case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
  215. ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
  216. goto out;
  217. case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
  218. ret = AVB_AB_FLOW_RESULT_ERROR_IO;
  219. goto out;
  220. case AVB_SLOT_VERIFY_RESULT_OK:
  221. break;
  222. case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
  223. case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
  224. /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
  225. * these mean game over.
  226. */
  227. set_slot_unbootable = true;
  228. break;
  229. /* explicit fallthrough. */
  230. case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
  231. case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
  232. case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
  233. if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
  234. /* Do nothing since we allow this. */
  235. avb_debugv("Allowing slot ",
  236. slot_suffixes[n],
  237. " which verified "
  238. "with result ",
  239. avb_slot_verify_result_to_string(verify_result),
  240. " because "
  241. "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
  242. "is set.\n",
  243. NULL);
  244. saw_and_allowed_verification_error = true;
  245. } else {
  246. set_slot_unbootable = true;
  247. }
  248. break;
  249. case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
  250. ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
  251. goto out;
  252. /* Do not add a 'default:' case here because of -Wswitch. */
  253. }
  254. if (set_slot_unbootable) {
  255. avb_errorv("Error verifying slot ",
  256. slot_suffixes[n],
  257. " with result ",
  258. avb_slot_verify_result_to_string(verify_result),
  259. " - setting unbootable.\n",
  260. NULL);
  261. slot_set_unbootable(&ab_data.slots[n]);
  262. }
  263. }
  264. }
  265. if (slot_is_bootable(&ab_data.slots[0]) &&
  266. slot_is_bootable(&ab_data.slots[1])) {
  267. if (ab_data.slots[1].priority > ab_data.slots[0].priority) {
  268. slot_index_to_boot = 1;
  269. } else {
  270. slot_index_to_boot = 0;
  271. }
  272. } else if (slot_is_bootable(&ab_data.slots[0])) {
  273. slot_index_to_boot = 0;
  274. } else if (slot_is_bootable(&ab_data.slots[1])) {
  275. slot_index_to_boot = 1;
  276. } else {
  277. /* No bootable slots! */
  278. avb_error("No bootable slots found.\n");
  279. ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
  280. goto out;
  281. }
  282. /* Update stored rollback index such that the stored rollback index
  283. * is the largest value supporting all currently bootable slots. Do
  284. * this for every rollback index location.
  285. */
  286. for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
  287. uint64_t rollback_index_value = 0;
  288. if (slot_data[0] != NULL && slot_data[1] != NULL) {
  289. uint64_t a_rollback_index = slot_data[0]->rollback_indexes[n];
  290. uint64_t b_rollback_index = slot_data[1]->rollback_indexes[n];
  291. rollback_index_value =
  292. (a_rollback_index < b_rollback_index ? a_rollback_index
  293. : b_rollback_index);
  294. } else if (slot_data[0] != NULL) {
  295. rollback_index_value = slot_data[0]->rollback_indexes[n];
  296. } else if (slot_data[1] != NULL) {
  297. rollback_index_value = slot_data[1]->rollback_indexes[n];
  298. }
  299. if (rollback_index_value != 0) {
  300. uint64_t current_rollback_index_value;
  301. io_ret = ops->read_rollback_index(ops, n, &current_rollback_index_value);
  302. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  303. ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
  304. goto out;
  305. } else if (io_ret != AVB_IO_RESULT_OK) {
  306. avb_error("Error getting rollback index for slot.\n");
  307. ret = AVB_AB_FLOW_RESULT_ERROR_IO;
  308. goto out;
  309. }
  310. if (current_rollback_index_value != rollback_index_value) {
  311. io_ret = ops->write_rollback_index(ops, n, rollback_index_value);
  312. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  313. ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
  314. goto out;
  315. } else if (io_ret != AVB_IO_RESULT_OK) {
  316. avb_error("Error setting stored rollback index.\n");
  317. ret = AVB_AB_FLOW_RESULT_ERROR_IO;
  318. goto out;
  319. }
  320. }
  321. }
  322. }
  323. /* Finally, select this slot. */
  324. avb_assert(slot_data[slot_index_to_boot] != NULL);
  325. data = slot_data[slot_index_to_boot];
  326. slot_data[slot_index_to_boot] = NULL;
  327. if (saw_and_allowed_verification_error) {
  328. avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
  329. ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
  330. } else {
  331. ret = AVB_AB_FLOW_RESULT_OK;
  332. }
  333. /* ... and decrement tries remaining, if applicable. */
  334. if (!ab_data.slots[slot_index_to_boot].successful_boot &&
  335. ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
  336. ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
  337. }
  338. out:
  339. io_ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  340. if (io_ret != AVB_IO_RESULT_OK) {
  341. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  342. ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
  343. } else {
  344. ret = AVB_AB_FLOW_RESULT_ERROR_IO;
  345. }
  346. if (data != NULL) {
  347. avb_slot_verify_data_free(data);
  348. data = NULL;
  349. }
  350. }
  351. for (n = 0; n < 2; n++) {
  352. if (slot_data[n] != NULL) {
  353. avb_slot_verify_data_free(slot_data[n]);
  354. }
  355. }
  356. if (out_data != NULL) {
  357. *out_data = data;
  358. } else {
  359. if (data != NULL) {
  360. avb_slot_verify_data_free(data);
  361. }
  362. }
  363. return ret;
  364. }
  365. AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops,
  366. unsigned int slot_number) {
  367. AvbABData ab_data, ab_data_orig;
  368. unsigned int other_slot_number;
  369. AvbIOResult ret;
  370. avb_assert(slot_number < 2);
  371. ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  372. if (ret != AVB_IO_RESULT_OK) {
  373. goto out;
  374. }
  375. /* Make requested slot top priority, unsuccessful, and with max tries. */
  376. ab_data.slots[slot_number].priority = AVB_AB_MAX_PRIORITY;
  377. ab_data.slots[slot_number].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  378. ab_data.slots[slot_number].successful_boot = 0;
  379. /* Ensure other slot doesn't have as high a priority. */
  380. other_slot_number = 1 - slot_number;
  381. if (ab_data.slots[other_slot_number].priority == AVB_AB_MAX_PRIORITY) {
  382. ab_data.slots[other_slot_number].priority = AVB_AB_MAX_PRIORITY - 1;
  383. }
  384. ret = AVB_IO_RESULT_OK;
  385. out:
  386. if (ret == AVB_IO_RESULT_OK) {
  387. ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  388. }
  389. return ret;
  390. }
  391. AvbIOResult avb_ab_mark_slot_unbootable(AvbABOps* ab_ops,
  392. unsigned int slot_number) {
  393. AvbABData ab_data, ab_data_orig;
  394. AvbIOResult ret;
  395. avb_assert(slot_number < 2);
  396. ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  397. if (ret != AVB_IO_RESULT_OK) {
  398. goto out;
  399. }
  400. slot_set_unbootable(&ab_data.slots[slot_number]);
  401. ret = AVB_IO_RESULT_OK;
  402. out:
  403. if (ret == AVB_IO_RESULT_OK) {
  404. ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  405. }
  406. return ret;
  407. }
  408. AvbIOResult avb_ab_mark_slot_successful(AvbABOps* ab_ops,
  409. unsigned int slot_number) {
  410. AvbABData ab_data, ab_data_orig;
  411. AvbIOResult ret;
  412. avb_assert(slot_number < 2);
  413. ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  414. if (ret != AVB_IO_RESULT_OK) {
  415. goto out;
  416. }
  417. if (!slot_is_bootable(&ab_data.slots[slot_number])) {
  418. avb_error("Cannot mark unbootable slot as successful.\n");
  419. ret = AVB_IO_RESULT_OK;
  420. goto out;
  421. }
  422. ab_data.slots[slot_number].tries_remaining = 0;
  423. ab_data.slots[slot_number].successful_boot = 1;
  424. ret = AVB_IO_RESULT_OK;
  425. out:
  426. if (ret == AVB_IO_RESULT_OK) {
  427. ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  428. }
  429. return ret;
  430. }
  431. const char* avb_ab_flow_result_to_string(AvbABFlowResult result) {
  432. const char* ret = NULL;
  433. switch (result) {
  434. case AVB_AB_FLOW_RESULT_OK:
  435. ret = "OK";
  436. break;
  437. case AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR:
  438. ret = "OK_WITH_VERIFICATION_ERROR";
  439. break;
  440. case AVB_AB_FLOW_RESULT_ERROR_OOM:
  441. ret = "ERROR_OOM";
  442. break;
  443. case AVB_AB_FLOW_RESULT_ERROR_IO:
  444. ret = "ERROR_IO";
  445. break;
  446. case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
  447. ret = "ERROR_NO_BOOTABLE_SLOTS";
  448. break;
  449. case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
  450. ret = "ERROR_INVALID_ARGUMENT";
  451. break;
  452. /* Do not add a 'default:' case here because of -Wswitch. */
  453. }
  454. if (ret == NULL) {
  455. avb_error("Unknown AvbABFlowResult value.\n");
  456. ret = "(unknown)";
  457. }
  458. return ret;
  459. }