libavb: Allow specifying dm-verity error handling.
Currently AVB only supports one error mode for handling dm-verity
errors which is to invalidate the slot in question and restart the
device. On the next reboot the bootloader is expected to boot the
other slot or enter some kind of repair state.
While this may be suitable for some devices / form-factors it doesn't
allow for the workflow described in "Recovering from dm-verity errors"
as described in
https://source.android.com/security/verifiedboot/verified-boot
This CL adds support for specifying the error mode by allowing passing
through the verity error handling mode to avb_slot_verify(). Initially
four error handling modes are supported
* AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE means that the HLOS
will invalidate the current slot and restart (current behavior).
* AVB_HASHTREE_ERROR_MODE_RESTART means that the OS will restart
(without the current slot being invalidated).
* AVB_HASHTREE_ERROR_MODE_EIO means that an EIO error will be
returned to the application.
* AVB_HASHTREE_ERROR_MODE_LOGGING means that errors will be logged
and corrupt data may be returned to applications. This mode should
be used ONLY for diagnostics and debugging. It cannot be used
unless also allow verification errors (e.g. only UNLOCKED mode).
The passed-in value combined with whether dm-verity is disabled in the
top-level vbmeta maps to androidboot.veritymode being either
'enforcing', 'eio', or 'logging' and
androidboot.vbmeta.invalidate_on_error maybe being set to 'yes'.
In a nutshell this CL simply sets androidboot.veritymode and
androidboot.vbmeta.invalidate_on_error based on whatever hashtree
error mode is passed by the caller of avb_slot_verify().
This CL also introduces $(ANDROID_VERITY_MODE) which is now used by
avbtool in the dm="..." string and libavb will replace this with
'restart_on_corruption', 'ignore_corruption', etc. depending on the
error handling mode passed to avb_slot_verity().
A related CL for drivers/md/dm-verity-avb.c will support
androidboot.vbmeta.invalidate_on_error to only invalidate if this is
set to 'yes'.
The README.md file has been updated with a section to discuss
dm-verity error handling and what it entails.
Since we're changing avb_slot_verify() with this CL also use this
opportunity to change the |allow_verification_mode| boolean parameter
into a flag. This will make it easier to add features to libavb in the
future without breaking API again.
Also update the toy UEFI bootloader in examples/uefi to use this new
API and make it use AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE.
Bug: 38157502
Test: New unit tests and all unit tests pass.
Test: Manually tested all dm-verity error modes on UEFI-based bootloader.
Change-Id: I2b9a3f227b5391a82ef131b6eb5acc22466f7492
diff --git a/README.md b/README.md
index 54805a0..a6d033e 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@
+ [Tamper-evident Storage](#Tamper_evident-Storage)
+ [Updating Stored Rollback Indexes](#Updating-Stored-Rollback-Indexes)
+ [Recommended Bootflow](#Recommended-Bootflow)
+ + [Handling dm-verity Errors](#Handling-dm_verity-Errors)
+ [Android Specific Integration](#Android-Specific-Integration)
# What is it?
@@ -488,16 +489,18 @@
In the context of AVB, the LOCKED state means that verification errors
are fatal whereas in UNLOCKED state they are not. If the device is
-UNLOCKED pass `true` in the `allow_verification_error` parameter of
-`avb_slot_verify()` and treat verification errors including
+UNLOCKED pass `AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR` flag in
+the `flags` parameter of `avb_slot_verify()` and treat verification
+errors including
* `AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED`
* `AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION`
* `AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX`
-as non-fatal. If the device is in the LOCKED state, pass `false` in
-the `allow_verification_error` parameter of `avb_slot_verify()` and
-only treat `AVB_SLOT_VERIFY_RESULT_OK` as non-fatal.
+as non-fatal. If the device is in the LOCKED state, don't pass the
+`AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR` flag in the `flags`
+parameter of `avb_slot_verify()` and only treat
+`AVB_SLOT_VERIFY_RESULT_OK` as non-fatal.
On Android, device state may be altered through the fastboot interface
using, e.g. `fastboot flashing lock` (to transition to the LOCKED
@@ -648,6 +651,71 @@
be used to convey that the device is UNLOCKED (lightbars, LEDs,
etc.).
+## Handling dm-verity Errors
+
+By design, hashtree verification errors are detected by the HLOS and
+not the bootloader. AVB provides a way to specify how the error should
+be handled through the `hashtree_error_mode` parameter in the
+`avb_slot_verify()` function. Possible values include
+
+* `AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE` means that the HLOS
+ will invalidate the current slot and restart. On devices with A/B
+ this would lead to attempting to boot the other slot (if it's marked
+ as bootable) or it could lead to a mode where no OS can be booted
+ (e.g. some form of repair mode).
+
+* `AVB_HASHTREE_ERROR_MODE_RESTART` means that the OS will restart
+ without the current slot being invalidated. Be careful using this
+ mode unconditionally as it may introduce boot loops if the same
+ hashtree verification error is hit on every boot.
+
+* `AVB_HASHTREE_ERROR_MODE_EIO` means that an `EIO` error will be
+ returned to the application.
+
+* `AVB_HASHTREE_ERROR_MODE_LOGGING` means that errors will be logged
+ and corrupt data may be returned to applications. This mode should
+ be used for **ONLY** diagnostics and debugging. It cannot be used
+ unless verification errors are allowed.
+
+The value passed in `hashtree_error_mode` is essentially just passed
+on through to the HLOS through the the `androidboot.veritymode` and
+`androidboot.vbmeta.invalidate_on_error` kernel command-line
+parameters. The HLOS - including the Linux kernel when using
+`CONFIG_DM_VERITY_AVB` - will then act upon hashtree verification
+errors as specified.
+
+### Which mode should I use for my device?
+
+This depends entirely on the device, how the device is intended to be
+used, and the desired user experience.
+
+For example, consider
+the
+[EIO mode in an earlier version of Android Verified Boot](https://source.android.com/security/verifiedboot/verified-boot) (see
+the "Recovering from dm-verity errors" section). In a nutshell this
+mode uses `AVB_HASHTREE_ERROR_MODE_RESTART` mode until an error is
+encounted and then it switches to `AVB_HASHTREE_ERROR_MODE_EIO` mode
+on the reboot. Additionally when in `AVB_HASHTREE_ERROR_MODE_EIO` mode
+the user is informed that the device experienced corruption and then
+asked to click through a screen to continue.
+
+To implement this mode in a boot loader, a combination of the
+`AVB_HASHTREE_ERROR_MODE_RESTART` mode and
+`AVB_HASHTREE_ERROR_MODE_EIO` mode could be used along with persistent
+storage recording what mode the bootloader is currently in. This would
+need to include transition rules e.g. if the kernel indicates that it
+rebooted because of a `dm-verity` error the bootloader would need to
+transition from the `AVB_HASHTREE_ERROR_MODE_RESTART` mode to the
+`AVB_HASHTREE_ERROR_MODE_EIO` mode. Ditto, when the slot is updated
+the bootloader needs to transition from the
+`AVB_HASHTREE_ERROR_MODE_EIO` mode back to the
+`AVB_HASHTREE_ERROR_MODE_RESTART` mode so the user doesn't have to
+click through a screen on every boot.
+
+On the other hand, if the device doesn't have a screen or if the HLOS
+supports multiple bootable slots simultaneously it may make more sense
+to just use `AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE`.
+
## Android Specific Integration
On Android, the boot loader must set the
diff --git a/avbtool b/avbtool
index 815caa0..08876a2 100755
--- a/avbtool
+++ b/avbtool
@@ -2081,7 +2081,7 @@
c += ' {}'.format(str(ht.salt).encode('hex')) # salt
if ht.fec_num_roots > 0:
c += ' 10' # number of optional args
- c += ' restart_on_corruption'
+ c += ' $(ANDROID_VERITY_MODE)'
c += ' ignore_zero_blocks'
c += ' use_fec_from_device PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'
c += ' fec_roots {}'.format(ht.fec_num_roots)
@@ -2092,7 +2092,7 @@
c += ' fec_start {}'.format(ht.fec_offset/ht.data_block_size)
else:
c += ' 2' # number of optional args
- c += ' restart_on_corruption'
+ c += ' $(ANDROID_VERITY_MODE)'
c += ' ignore_zero_blocks'
c += '" root=/dev/dm-0'
diff --git a/examples/uefi/main.c b/examples/uefi/main.c
index f493699..01dae48 100644
--- a/examples/uefi/main.c
+++ b/examples/uefi/main.c
@@ -39,6 +39,7 @@
const char* requested_partitions[] = {"boot", NULL};
bool unlocked = true;
char* additional_cmdline = NULL;
+ AvbSlotVerifyFlags flags;
InitializeLib(ImageHandle, SystemTable);
@@ -60,9 +61,15 @@
"\n",
NULL);
+ flags = AVB_SLOT_VERIFY_FLAGS_NONE;
+ if (unlocked) {
+ flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
+ }
+
ab_result = avb_ab_flow(ops->ab_ops,
requested_partitions,
- unlocked /* allow_verification_error */,
+ flags,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data);
avb_printv("avb_ab_flow() returned ",
avb_ab_flow_result_to_string(ab_result),
@@ -112,6 +119,9 @@
case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
avb_fatal("No bootable slots - enter repair mode\n");
break;
+ case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
+ avb_fatal("Invalid arguments passed\n");
+ break;
}
uefi_avb_ops_free(ops);
diff --git a/libavb/avb_slot_verify.c b/libavb/avb_slot_verify.c
index 3218605..39cad4f 100644
--- a/libavb/avb_slot_verify.c
+++ b/libavb/avb_slot_verify.c
@@ -56,6 +56,7 @@
case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
return false;
case AVB_SLOT_VERIFY_RESULT_OK:
@@ -949,13 +950,18 @@
AvbSlotVerifyResult avb_slot_verify(AvbOps* ops,
const char* const* requested_partitions,
const char* ab_suffix,
- bool allow_verification_error,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data) {
AvbSlotVerifyResult ret;
AvbSlotVerifyData* slot_data = NULL;
AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE;
AvbIOResult io_ret;
bool using_boot_for_vbmeta = false;
+ AvbVBMetaImageHeader toplevel_vbmeta;
+ const char* verity_mode;
+ bool allow_verification_error =
+ (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
/* Fail early if we're missing the AvbOps needed for slot verification.
*
@@ -973,6 +979,16 @@
*out_data = NULL;
}
+ /* Allowing dm-verity errors defeats the purpose of verified boot so
+ * only allow this if set up to allow verification errors
+ * (e.g. typically only UNLOCKED mode).
+ */
+ if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_LOGGING &&
+ !allow_verification_error) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
+ goto fail;
+ }
+
slot_data = avb_calloc(sizeof(AvbSlotVerifyData));
if (slot_data == NULL) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
@@ -1007,14 +1023,19 @@
goto fail;
}
- if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) {
- avb_assert(avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") ==
- 0);
- using_boot_for_vbmeta = true;
- }
-
/* If things check out, mangle the kernel command-line as needed. */
if (result_should_continue(ret)) {
+ if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) {
+ avb_assert(
+ avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0);
+ using_boot_for_vbmeta = true;
+ }
+
+ /* Byteswap top-level vbmeta header since we'll need it below. */
+ avb_vbmeta_image_header_to_host_byte_order(
+ (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data,
+ &toplevel_vbmeta);
+
/* Fill in |ab_suffix| field. */
slot_data->ab_suffix = avb_strdup(ab_suffix);
if (slot_data->ab_suffix == NULL) {
@@ -1130,6 +1151,55 @@
break;
}
+ /* Set androidboot.veritymode and androidboot.vbmeta.invalidate_on_error */
+ if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) {
+ verity_mode = "disabled";
+ } else {
+ const char* dm_verity_mode;
+ char* new_ret;
+
+ switch (hashtree_error_mode) {
+ case AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE:
+ if (!cmdline_append_option(
+ slot_data, "androidboot.vbmeta.invalidate_on_error", "yes")) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+ goto fail;
+ }
+ verity_mode = "enforcing";
+ dm_verity_mode = "restart_on_corruption";
+ break;
+ case AVB_HASHTREE_ERROR_MODE_RESTART:
+ verity_mode = "enforcing";
+ dm_verity_mode = "restart_on_corruption";
+ break;
+ case AVB_HASHTREE_ERROR_MODE_EIO:
+ verity_mode = "eio";
+ /* For now there's no option to specify the EIO mode. So
+ * just use 'ignore_zero_blocks' since that's already set
+ * and dm-verity-target.c supports specifying this multiple
+ * times.
+ */
+ dm_verity_mode = "ignore_zero_blocks";
+ break;
+ case AVB_HASHTREE_ERROR_MODE_LOGGING:
+ verity_mode = "logging";
+ dm_verity_mode = "ignore_corruption";
+ break;
+ }
+ new_ret = avb_replace(
+ slot_data->cmdline, "$(ANDROID_VERITY_MODE)", dm_verity_mode);
+ avb_free(slot_data->cmdline);
+ slot_data->cmdline = new_ret;
+ if (slot_data->cmdline == NULL) {
+ goto fail;
+ }
+ }
+ if (!cmdline_append_option(
+ slot_data, "androidboot.veritymode", verity_mode)) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+ goto fail;
+ }
+
if (out_data != NULL) {
*out_data = slot_data;
} else {
@@ -1214,6 +1284,9 @@
case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
ret = "ERROR_UNSUPPORTED_VERSION";
break;
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+ ret = "ERROR_INVALID_ARGUMENT";
+ break;
/* Do not add a 'default:' case here because of -Wswitch. */
}
diff --git a/libavb/avb_slot_verify.h b/libavb/avb_slot_verify.h
index ff9d985..e7c010d 100644
--- a/libavb/avb_slot_verify.h
+++ b/libavb/avb_slot_verify.h
@@ -50,9 +50,61 @@
AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
- AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION
+ AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION,
+ AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT
} AvbSlotVerifyResult;
+/* Various error handling modes for when verification fails using a
+ * hashtree at runtime inside the HLOS.
+ *
+ * AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE means that the OS
+ * will invalidate the current slot and restart.
+ *
+ * AVB_HASHTREE_ERROR_MODE_RESTART means that the OS will restart.
+ *
+ * AVB_HASHTREE_ERROR_MODE_EIO means that an EIO error will be
+ * returned to applications.
+ *
+ * AVB_HASHTREE_ERROR_MODE_LOGGING means that errors will be logged
+ * and corrupt data may be returned to applications. This mode should
+ * be used ONLY for diagnostics and debugging. It cannot be used
+ * unless AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is also
+ * used.
+ */
+typedef enum {
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
+ AVB_HASHTREE_ERROR_MODE_RESTART,
+ AVB_HASHTREE_ERROR_MODE_EIO,
+ AVB_HASHTREE_ERROR_MODE_LOGGING
+} AvbHashtreeErrorMode;
+
+/* Flags that influence how avb_slot_verify() works.
+ *
+ * If AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is NOT set then
+ * avb_slot_verify() will bail out as soon as an error is encountered
+ * and |out_data| is set only if AVB_SLOT_VERIFY_RESULT_OK is
+ * returned.
+ *
+ * Otherwise if AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is set
+ * avb_slot_verify() will continue verification efforts and |out_data|
+ * is also set if AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
+ * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or
+ * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX is returned. It is
+ * undefined which error is returned if more than one distinct error
+ * is encountered. It is guaranteed that AVB_SLOT_VERIFY_RESULT_OK is
+ * returned if, and only if, there are no errors. This mode is needed
+ * to boot valid but unverified slots when the device is unlocked.
+ *
+ * Also, if AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is set the
+ * contents loaded from |requested_partition| will be the contents of
+ * the entire partition instead of just the size specified in the hash
+ * descriptor.
+ */
+typedef enum {
+ AVB_SLOT_VERIFY_FLAGS_NONE = 0,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR = (1 << 0)
+} AvbSlotVerifyFlags;
+
/* Get a textual representation of |result|. */
const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result);
@@ -135,11 +187,25 @@
* performing proper substitution of the variables
* $(ANDROID_SYSTEM_PARTUUID), $(ANDROID_BOOT_PARTUUID), and
* $(ANDROID_VBMETA_PARTUUID) using the
- * get_unique_guid_for_partition() operation in |AvbOps|.
+ * get_unique_guid_for_partition() operation in |AvbOps|. Additionally
+ * $(ANDROID_VERITY_MODE) will be replaced with the proper dm-verity
+ * option depending on the value of |hashtree_error_mode|.
*
* Additionally, the |cmdline| field will have the following kernel
* command-line options set:
*
+ * androidboot.veritymode: This is set to 'disabled' if the
+ * AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED flag is set in top-level
+ * vbmeta struct. Otherwise it is set to 'enforcing' if the
+ * passed-in hashtree error mode is AVB_HASHTREE_ERROR_MODE_RESTART
+ * or AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 'eio' if it's
+ * set to AVB_HASHTREE_ERROR_MODE_EIO, and 'logging' if it's set to
+ * AVB_HASHTREE_ERROR_MODE_LOGGING.
+ *
+ * androidboot.vbmeta.invalidate_on_error: This is set to 'yes' only
+ * if hashtree validation isn't disabled and the passed-in hashtree
+ * error mode is AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE.
+ *
* androidboot.vbmeta.device_state: set to "locked" or "unlocked"
* depending on the result of the result of AvbOps's
* read_is_unlocked() function.
@@ -165,6 +231,11 @@
* set in the |cmdline| field in |AvbSlotVerifyData| - you will have
* to pass these yourself.
*
+ * Also note that androidboot.veritymode is set by libavb and since
+ * AVB only supports 'enforcing' and 'disabled' values, the boot
+ * loader is relieved of managing any state related to dm-verity or
+ * setting this cmdline parameter.
+ *
* This struct may grow in the future without it being considered an
* ABI break.
*/
@@ -204,24 +275,17 @@
* avb_slot_verify_data_free() when you are done with it. See below
* for when this is returned.
*
- * If |allow_verification_error| is false this function will bail out
- * as soon as an error is encountered and |out_data| is set only if
- * AVB_SLOT_VERIFY_RESULT_OK is returned.
+ * The |flags| parameter is used to influence the semantics of
+ * avb_slot_verify() - for example the
+ * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR flag can be used to
+ * ignore verification errors which is something needed in the
+ * UNLOCKED state. See the AvbSlotVerifyFlags enumeration for details.
*
- * Otherwise if |allow_verification_error| is true the function will
- * continue verification efforts and |out_data| is also set if
- * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
- * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or
- * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX is returned. It is
- * undefined which error is returned if more than one distinct error
- * is encountered. It is guaranteed that AVB_SLOT_VERIFY_RESULT_OK is
- * returned if, and only if, there are no errors. This mode is needed
- * to boot valid but unverified slots when the device is unlocked.
- *
- * Also, if |allow_verification_error| is true then the contents
- * loaded from |requested_partition| will be the contents of the
- * entire partition instead of just the size specified in the hash
- * descriptor.
+ * The |hashtree_error_mode| parameter should be set the desired error
+ * handling mode when hashtree validation fails inside the HLOS. This
+ * value isn't used by libavb per se - it is forwarded to the HLOS
+ * through the androidboot.veritymode cmdline parameter. See the
+ * AvbHashtreeErrorMode enumeration for details.
*
* Also note that |out_data| is never set if
* AVB_SLOT_VERIFY_RESULT_ERROR_OOM, AVB_SLOT_VERIFY_RESULT_ERROR_IO,
@@ -254,11 +318,17 @@
* AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION is returned if
* some of the metadata requires a newer version of libavb than what
* is in use.
+ *
+ * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT is returned if the
+ * caller passed invalid parameters, for example trying to use
+ * AVB_HASHTREE_ERROR_MODE_LOGGING without
+ * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
*/
AvbSlotVerifyResult avb_slot_verify(AvbOps* ops,
const char* const* requested_partitions,
const char* ab_suffix,
- bool allow_verification_error,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
#ifdef __cplusplus
diff --git a/libavb_ab/avb_ab_flow.c b/libavb_ab/avb_ab_flow.c
index 3adb927..e0661fa 100644
--- a/libavb_ab/avb_ab_flow.c
+++ b/libavb_ab/avb_ab_flow.c
@@ -204,7 +204,8 @@
AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
const char* const* requested_partitions,
- bool allow_verification_error,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data) {
AvbOps* ops = ab_ops->ops;
AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
@@ -233,7 +234,8 @@
verify_result = avb_slot_verify(ops,
requested_partitions,
slot_suffixes[n],
- allow_verification_error,
+ flags,
+ hashtree_error_mode,
&slot_data[n]);
switch (verify_result) {
case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
@@ -249,7 +251,9 @@
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
- /* Even with |allow_verification_error| these mean game over. */
+ /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
+ * these mean game over.
+ */
set_slot_unbootable = true;
break;
@@ -257,20 +261,27 @@
case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
- if (allow_verification_error) {
+ if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
/* Do nothing since we allow this. */
avb_debugv("Allowing slot ",
slot_suffixes[n],
" which verified "
"with result ",
avb_slot_verify_result_to_string(verify_result),
- " because |allow_verification_error| is true.\n",
+ " because "
+ "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
+ "is set.\n",
NULL);
saw_and_allowed_verification_error = true;
} else {
set_slot_unbootable = true;
}
break;
+
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+ ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
+ goto out;
+ /* Do not add a 'default:' case here because of -Wswitch. */
}
if (set_slot_unbootable) {
@@ -352,7 +363,7 @@
data = slot_data[slot_index_to_boot];
slot_data[slot_index_to_boot] = NULL;
if (saw_and_allowed_verification_error) {
- avb_assert(allow_verification_error);
+ avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
} else {
ret = AVB_AB_FLOW_RESULT_OK;
@@ -504,6 +515,9 @@
case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
ret = "ERROR_NO_BOOTABLE_SLOTS";
break;
+ case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
+ ret = "ERROR_INVALID_ARGUMENT";
+ break;
/* Do not add a 'default:' case here because of -Wswitch. */
}
diff --git a/libavb_ab/avb_ab_flow.h b/libavb_ab/avb_ab_flow.h
index 44e7d0e..588026d 100644
--- a/libavb_ab/avb_ab_flow.h
+++ b/libavb_ab/avb_ab_flow.h
@@ -140,7 +140,8 @@
AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
AVB_AB_FLOW_RESULT_ERROR_OOM,
AVB_AB_FLOW_RESULT_ERROR_IO,
- AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS
+ AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
+ AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT
} AvbABFlowResult;
/* Get a textual representation of |result|. */
@@ -156,9 +157,9 @@
*
* 2. All bootable slots listed in the A/B metadata are verified using
* avb_slot_verify(). If a slot is invalid or if it fails verification
- * (and |allow_verification_error| is false, see below), it will be
- * marked as unbootable in the A/B metadata and the metadata will be
- * saved to disk before returning.
+ * (and AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is not set, see
+ * below), it will be marked as unbootable in the A/B metadata and the
+ * metadata will be saved to disk before returning.
*
* 3. If there are no bootable slots, the value
* AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS is returned.
@@ -180,10 +181,10 @@
* |requested_partitions| array only contains a single item for the
* boot partition, 'boot'.
*
- * If the device is unlocked (and _only_ if it's unlocked), true
- * should be passed in the |allow_verification_error| parameter. This
- * will allow considering slots as verified even when
- * avb_slot_verify() returns
+ * If the device is unlocked (and _only_ if it's unlocked), the
+ * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR flag should be set
+ * in the |flags| parameter. This will allow considering slots as
+ * verified even when avb_slot_verify() returns
* AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
* AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or
* AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX for the slot in
@@ -198,7 +199,8 @@
*
* If a slot was selected but it didn't verify then
* AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR is returned. This can
- * only happen when |allow_verification_error| is true.
+ * only happen when the AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
+ * flag is set.
*
* If an I/O operation - such as loading/saving metadata or checking
* rollback indexes - fail, the value AVB_AB_FLOW_RESULT_ERROR_IO is
@@ -207,12 +209,18 @@
* If memory allocation fails, AVB_AB_FLOW_RESULT_ERROR_OOM is
* returned.
*
+ * If invalid arguments are passed,
+ * AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT is returned. For example
+ * this can happen if using AVB_HASHTREE_ERROR_MODE_LOGGING without
+ * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
+ *
* Reasonable behavior for handling AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS
* is to initiate device repair (which is device-dependent).
*/
AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
const char* const* requested_partitions,
- bool allow_verification_error,
+ AvbSlotVerifyFlags flags,
+ AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
/* Marks the slot with the given slot number as active. Returns
diff --git a/test/avb_ab_flow_unittest.cc b/test/avb_ab_flow_unittest.cc
index 63c81dc..3d16b60 100644
--- a/test/avb_ab_flow_unittest.cc
+++ b/test/avb_ab_flow_unittest.cc
@@ -331,7 +331,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(14,
0,
@@ -361,7 +362,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -395,7 +397,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -428,7 +431,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
2,
@@ -445,7 +449,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
1,
@@ -462,7 +467,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -480,7 +486,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -512,7 +519,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
1,
@@ -529,7 +537,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -546,7 +555,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -580,7 +590,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -615,7 +626,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -645,7 +657,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -675,7 +688,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -708,7 +722,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -738,7 +753,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -768,7 +784,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -801,7 +818,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -831,7 +849,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -865,7 +884,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -896,7 +916,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -928,7 +949,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(0,
0,
@@ -1155,7 +1177,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(14,
0,
@@ -1185,7 +1208,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
@@ -1228,7 +1252,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(14,
0,
@@ -1258,7 +1283,8 @@
EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
avb_ab_flow(ops_.avb_ab_ops(),
requested_partitions,
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&data));
ExpMD(15,
0,
diff --git a/test/avb_atx_validate_unittest.cc b/test/avb_atx_validate_unittest.cc
index 08ddf8e..8dd60a3 100644
--- a/test/avb_atx_validate_unittest.cc
+++ b/test/avb_atx_validate_unittest.cc
@@ -660,7 +660,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
diff --git a/test/avb_slot_verify_unittest.cc b/test/avb_slot_verify_unittest.cc
index 124ccdd..d8c414a 100644
--- a/test/avb_slot_verify_unittest.cc
+++ b/test/avb_slot_verify_unittest.cc
@@ -65,7 +65,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
@@ -74,7 +75,9 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
"androidboot.vbmeta.digest="
- "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
+ "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
avb_slot_verify_data_free(slot_data);
}
@@ -95,7 +98,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
@@ -105,7 +109,9 @@
"androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
"androidboot.vbmeta.digest="
"cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
- "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
+ "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
avb_slot_verify_data_free(slot_data);
}
@@ -128,7 +134,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
@@ -137,7 +144,9 @@
"androidboot.vbmeta.device_state=unlocked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
"androidboot.vbmeta.digest="
- "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
+ "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
avb_slot_verify_data_free(slot_data);
}
@@ -158,7 +167,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -177,14 +187,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -197,7 +209,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
}
@@ -215,14 +228,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -252,14 +267,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -291,7 +308,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
}
@@ -316,7 +334,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -328,14 +347,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -395,7 +416,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
@@ -482,7 +504,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
@@ -517,7 +540,9 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
"androidboot.vbmeta.digest="
- "34cdb59b955aa35d4da97701f304fabf7392eecca8c50ff1a0b7b6e1c9aaa1b8",
+ "34cdb59b955aa35d4da97701f304fabf7392eecca8c50ff1a0b7b6e1c9aaa1b8 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
EXPECT_EQ(4UL, slot_data->rollback_indexes[0]);
for (size_t n = 1; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
@@ -564,7 +589,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -582,14 +608,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -688,7 +716,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
@@ -754,7 +783,9 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
"androidboot.vbmeta.digest="
- "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
+ "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
@@ -805,7 +836,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -823,14 +855,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -882,14 +916,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -940,7 +976,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -953,14 +990,16 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- true /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
avb_slot_verify_data_free(slot_data);
@@ -973,7 +1012,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
}
@@ -1043,7 +1083,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
@@ -1078,7 +1119,9 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
"androidboot.vbmeta.digest="
- "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
+ "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
@@ -1161,7 +1204,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
@@ -1216,7 +1260,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
@@ -1225,7 +1270,9 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
"androidboot.vbmeta.digest="
- "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0",
+ "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
avb_slot_verify_data_free(slot_data);
}
@@ -1290,7 +1337,7 @@
"1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
"PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
"e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
- "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
+ "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
" Kernel Cmdline descriptor:\n"
" Flags: 2\n"
" Kernel Cmdline: "
@@ -1313,7 +1360,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
if (hashtree_verification_on) {
@@ -1329,9 +1377,13 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
"androidboot.vbmeta.digest="
- "51ea1638d8cc19a7a15b2bade22d155fb5150a6e376171ea1a89b7d6c89d6f17",
+ "946996b4cd78f2c060f6bb062b94054b809cbfbe9bf4425df263a0e55395ceea "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
} else {
+ // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
+ // androidboot.vbmeta.invalidate_on_error isn't set.
EXPECT_EQ(
"root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
@@ -1339,7 +1391,8 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
"androidboot.vbmeta.digest="
- "877daa21c04df1d9e1776bc6169c98de947ce44b1b34b545021bb3f34e287da6",
+ "c74338b2b366f7f774d264abb4ac06c997cbaacbf5edd70a6ef1a552f744076b "
+ "androidboot.veritymode=disabled",
std::string(slot_data->cmdline));
}
avb_slot_verify_data_free(slot_data);
@@ -1460,7 +1513,7 @@
" Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 32768 verity 1 "
"PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
"4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
- "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
+ "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
" Kernel Cmdline descriptor:\n"
" Flags: 2\n"
" Kernel Cmdline: "
@@ -1508,7 +1561,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_NE(nullptr, slot_data);
// Note 'boot' in the value androidboot.vbmeta.device since we've
@@ -1523,7 +1577,9 @@
"androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5312 "
"androidboot.vbmeta.digest="
- "87bf39949a560f93d54aa0a5e9d158439110141246e40fb103f131633a3ca456",
+ "6b06719a940e5d8fa53ffef91eb4f0517ff0dda9833b90be1c9624ab3a5261d2 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
avb_slot_verify_data_free(slot_data);
}
@@ -1576,7 +1632,8 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
}
@@ -1630,9 +1687,171 @@
avb_slot_verify(ops_.avb_ops(),
requested_partitions,
"_a",
- false /* allow_verification_error */,
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data));
EXPECT_EQ(nullptr, slot_data);
}
+TEST_F(AvbSlotVerifyTest, HashtreeErrorModes) {
+ const size_t MiB = 1024 * 1024;
+ const size_t system_size = 16 * MiB;
+ const size_t system_part_size = 32 * MiB;
+ base::FilePath system_path = GenerateImage("system.img", system_size);
+
+ EXPECT_COMMAND(0,
+ "./avbtool add_hashtree_footer --salt d00df00d --image %s "
+ "--partition_size %d --partition_name system "
+ "--algorithm SHA256_RSA2048 "
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
+ system_path.value().c_str(),
+ (int)system_part_size);
+
+ GenerateVBMetaImage("vbmeta.img",
+ "SHA256_RSA2048",
+ 0,
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ base::StringPrintf("--setup_rootfs_from_kernel %s "
+ "--include_descriptors_from_image %s"
+ " --internal_release_string \"\"",
+ system_path.value().c_str(),
+ system_path.value().c_str()));
+
+ ops_.set_expected_public_key(
+ PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
+
+ AvbSlotVerifyData* slot_data = NULL;
+ const char* requested_partitions[] = {"boot", NULL};
+
+ // For AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE we should get
+ // androidboot.vbmeta.invalidate_on_error=yes and
+ // androidboot.veritymode=enforcing. We should get
+ // 'restart_on_corruption' in the dm="..." string.
+ EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
+ avb_slot_verify(ops_.avb_ops(),
+ requested_partitions,
+ "",
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
+ &slot_data));
+ EXPECT_NE(nullptr, slot_data);
+ EXPECT_EQ(
+ "dm=\"1 vroot none ro 1,0 32768 verity 1 "
+ "PARTUUID=1234-fake-guid-for:system "
+ "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
+ "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
+ "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
+ "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.hash_alg=sha256 "
+ "androidboot.vbmeta.size=1664 "
+ "androidboot.vbmeta.digest="
+ "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
+ "androidboot.vbmeta.invalidate_on_error=yes "
+ "androidboot.veritymode=enforcing",
+ std::string(slot_data->cmdline));
+ avb_slot_verify_data_free(slot_data);
+
+ // For AVB_HASHTREE_ERROR_MODE_RESTART we should get
+ // androidboot.veritymode=enforcing and
+ // androidboot.vbmeta.invalidate_on_error should be unset. We should
+ // get 'restart_on_corruption' in the dm="..." string.
+ EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
+ avb_slot_verify(ops_.avb_ops(),
+ requested_partitions,
+ "",
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_RESTART,
+ &slot_data));
+ EXPECT_NE(nullptr, slot_data);
+ EXPECT_EQ(
+ "dm=\"1 vroot none ro 1,0 32768 verity 1 "
+ "PARTUUID=1234-fake-guid-for:system "
+ "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
+ "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
+ "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
+ "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.hash_alg=sha256 "
+ "androidboot.vbmeta.size=1664 "
+ "androidboot.vbmeta.digest="
+ "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
+ "androidboot.veritymode=enforcing",
+ std::string(slot_data->cmdline));
+ avb_slot_verify_data_free(slot_data);
+
+ // For AVB_HASHTREE_ERROR_MODE_EIO we should get
+ // androidboot.veritymode=eio and
+ // androidboot.vbmeta.invalidate_on_error should be unset. We should
+ // get 'ignore_zero_blocks' in the dm="..." string.
+ EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
+ avb_slot_verify(ops_.avb_ops(),
+ requested_partitions,
+ "",
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_EIO,
+ &slot_data));
+ EXPECT_NE(nullptr, slot_data);
+ EXPECT_EQ(
+ "dm=\"1 vroot none ro 1,0 32768 verity 1 "
+ "PARTUUID=1234-fake-guid-for:system "
+ "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
+ "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
+ "ignore_zero_blocks ignore_zero_blocks\" root=/dev/dm-0 "
+ "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.hash_alg=sha256 "
+ "androidboot.vbmeta.size=1664 "
+ "androidboot.vbmeta.digest="
+ "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
+ "androidboot.veritymode=eio",
+ std::string(slot_data->cmdline));
+ avb_slot_verify_data_free(slot_data);
+
+ // For AVB_HASHTREE_ERROR_MODE_LOGGING we should get
+ // androidboot.veritymode=logging and
+ // androidboot.vbmeta.invalidate_on_error should be unset. We should
+ // get 'ignore_corruption' in the dm="..." string.
+ //
+ // Check AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT is returned
+ // unless we pass AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
+ EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT,
+ avb_slot_verify(ops_.avb_ops(),
+ requested_partitions,
+ "",
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_LOGGING,
+ &slot_data));
+ EXPECT_EQ(nullptr, slot_data);
+ // --
+ EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
+ avb_slot_verify(ops_.avb_ops(),
+ requested_partitions,
+ "",
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
+ AVB_HASHTREE_ERROR_MODE_LOGGING,
+ &slot_data));
+ EXPECT_NE(nullptr, slot_data);
+ EXPECT_EQ(
+ "dm=\"1 vroot none ro 1,0 32768 verity 1 "
+ "PARTUUID=1234-fake-guid-for:system "
+ "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
+ "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
+ "ignore_corruption ignore_zero_blocks\" root=/dev/dm-0 "
+ "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.hash_alg=sha256 "
+ "androidboot.vbmeta.size=1664 "
+ "androidboot.vbmeta.digest="
+ "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
+ "androidboot.veritymode=logging",
+ std::string(slot_data->cmdline));
+ avb_slot_verify_data_free(slot_data);
+}
+
} // namespace avb
diff --git a/test/avbtool_unittest.cc b/test/avbtool_unittest.cc
index 4d9f2a8..b9d058a 100644
--- a/test/avbtool_unittest.cc
+++ b/test/avbtool_unittest.cc
@@ -886,7 +886,7 @@
" Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity 1 "
"PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
"4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
- "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
+ "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
" Kernel Cmdline descriptor:\n"
" Flags: 2\n"
" Kernel Cmdline: "
@@ -1114,7 +1114,7 @@
" Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity 1 "
"PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
"4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
- "d00df00d 10 restart_on_corruption ignore_zero_blocks "
+ "d00df00d 10 $(ANDROID_VERITY_MODE) ignore_zero_blocks "
"use_fec_from_device "
"PARTUUID=$(ANDROID_SYSTEM_PARTUUID) fec_roots 2 fec_blocks 261 "
"fec_start 261\" root=/dev/dm-0'\n"