[U-Boot] [PATCH 5/8] avb2.0: add boot states and dm-verity support
Sam Protsenko
semen.protsenko at linaro.org
Wed May 2 18:59:28 UTC 2018
On 25 April 2018 at 16:18, Igor Opaniuk <igor.opaniuk at linaro.org> wrote:
> 1. Add initial support of boot states mode (red, green, yellow)
> 2. Add functions for enforcing dm-verity configurations
>
> Signed-off-by: Igor Opaniuk <igor.opaniuk at linaro.org>
> ---
> cmd/avb.c | 17 ++++++-
> common/avb_verify.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++--
> include/avb_verify.h | 19 ++++++-
> 3 files changed, 171 insertions(+), 5 deletions(-)
>
> diff --git a/cmd/avb.c b/cmd/avb.c
> index d040906..2c15b47 100644
> --- a/cmd/avb.c
> +++ b/cmd/avb.c
> @@ -218,6 +218,8 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag,
> {
> AvbSlotVerifyResult slot_result;
> AvbSlotVerifyData *out_data;
> + char *cmdline;
> + char *extra_args;
>
> bool unlocked = false;
> int res = CMD_RET_FAILURE;
> @@ -243,10 +245,23 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag,
> "", unlocked, &out_data);
> switch (slot_result) {
> case AVB_SLOT_VERIFY_RESULT_OK:
> + /* Until we don't have support of changing unlock states, we
> + * assume that we are by default in locked state.
> + * So in this case we can boot only when verification is
> + * successful; we also supply in cmdline GREEN boot state
> + */
> printf("Verification passed successfully\n");
>
> /* export additional bootargs to AVB_BOOTARGS env var */
> - env_set(AVB_BOOTARGS, out_data->cmdline);
> +
> + extra_args = avb_set_state(avb_ops, AVB_GREEN);
> + if (extra_args)
> + cmdline = append_cmd_line(out_data->cmdline,
> + extra_args);
> + else
> + cmdline = out_data->cmdline;
> +
> + env_set(AVB_BOOTARGS, cmdline);
>
> res = CMD_RET_SUCCESS;
> break;
> diff --git a/common/avb_verify.c b/common/avb_verify.c
> index b3d1229..df5e407 100644
> --- a/common/avb_verify.c
> +++ b/common/avb_verify.c
> @@ -119,6 +119,140 @@ const unsigned char avb_root_pub[1032] = {
>
> /**
> * ============================================================================
> + * Boot states support (GREEN, YELLOW, ORANGE, RED) and dm_verity
> + * ============================================================================
> + */
> +char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state)
> +{
> + struct AvbOpsData *data;
> + char *cmdline = NULL;
> +
> + if (!ops)
> + return NULL;
> +
> + data = (struct AvbOpsData *)ops->user_data;
> + if (!data)
> + return NULL;
> +
> + data->boot_state = boot_state;
> + switch (boot_state) {
> + case AVB_GREEN:
> + cmdline = "androidboot.verifiedbootstate=green";
> + break;
> + case AVB_YELLOW:
> + cmdline = "androidboot.verifiedbootstate=yellow";
> + break;
> + case AVB_ORANGE:
> + cmdline = "androidboot.verifiedbootstate=orange";
> + case AVB_RED:
> + break;
> + }
> +
> + return cmdline;
> +}
> +
> +char *append_cmd_line(char *cmdline_orig, char *cmdline_new)
> +{
> + char *cmd_line;
> +
> + if (!cmdline_new)
> + return cmdline_orig;
> +
> + if (cmdline_orig)
> + cmd_line = cmdline_orig;
> + else
> + cmd_line = " ";
> +
> + cmd_line = avb_strdupv(cmd_line, " ", cmdline_new, NULL);
> +
> + return cmd_line;
> +}
> +
> +static int avb_find_dm_args(char **args, char *str)
> +{
> + int i = 0;
> +
> + if (!str)
> + return -1;
> +
> + do {
> + if ((!args[i]) || (i >= AVB_MAX_ARGS))
Conditions probably should be swapped, to avoid "index out of bounds" error.
> + return -1;
> +
> + if (strstr(args[i], str))
> + return i;
> +
> + i++;
> + } while (1);
> +}
Just a suggestion: wouldn't it be better to use "for" instead of
"do/while" here? Like this:
for (i = 0; i < AVB_MAX_ARGS, args[i]; ++i) {
if (strstr(args[i], str))
return i;
}
return -1;
> +
> +static char *avb_set_enforce_option(const char *cmdline, const char *option)
> +{
> + char *cmdarg[AVB_MAX_ARGS];
> + char *newargs = NULL;
> + int i = 0;
> + int total_args;
> +
> + memset(cmdarg, 0, sizeof(cmdarg));
> + cmdarg[i++] = strtok((char *)cmdline, " ");
> +
> + do {
> + cmdarg[i] = strtok(NULL, " ");
> + if (!cmdarg[i])
> + break;
> +
> + if (++i >= AVB_MAX_ARGS) {
> + printf("%s: Can't handle more then %d args\n",
> + __func__, i);
> + return NULL;
> + }
> + } while (true);
> +
> + total_args = i;
> + i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_LOGGING);
> + if (i >= 0) {
> + cmdarg[i] = (char *)option;
> + } else {
> + i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_RESTART);
> + if (i < 0) {
> + printf("%s: No verity options found\n", __func__);
> + return NULL;
> + }
> +
> + cmdarg[i] = (char *)option;
> + }
> +
> + for (i = 0; i <= total_args; i++)
> + newargs = append_cmd_line(newargs, cmdarg[i]);
> +
> + return newargs;
> +}
> +
> +char *avb_set_ignore_corruption(const char *cmdline)
> +{
> + char *newargs = NULL;
> +
> + newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_LOGGING);
> + if (newargs)
> + newargs = append_cmd_line(newargs,
> + "androidboot.veritymode=eio");
> +
> + return newargs;
> +}
> +
> +char *avb_set_enforce_verity(const char *cmdline)
> +{
> + char *newargs;
> +
> + newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_RESTART);
> + if (newargs)
> + newargs = append_cmd_line(newargs,
> + "androidboot.veritymode=enforcing");
> + return newargs;
> +}
> +
> +/**
> + * ============================================================================
> * IO(mmc) auxiliary functions
> * ============================================================================
> */
> @@ -478,7 +612,7 @@ static AvbIOResult read_rollback_index(AvbOps *ops,
> u64 *out_rollback_index)
> {
> /* For now we always return 0 as the stored rollback index. */
> - printf("TODO: implement %s.\n", __func__);
> + printf("%s not supported yet\n", __func__);
>
> if (out_rollback_index)
> *out_rollback_index = 0;
> @@ -502,7 +636,7 @@ static AvbIOResult write_rollback_index(AvbOps *ops,
> u64 rollback_index)
> {
> /* For now this is a no-op. */
> - printf("TODO: implement %s.\n", __func__);
> + printf("%s not supported yet\n", __func__);
>
> return AVB_IO_RESULT_OK;
> }
> @@ -522,7 +656,7 @@ static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
> {
> /* For now we always return that the device is unlocked. */
>
> - printf("TODO: implement %s.\n", __func__);
> + printf("%s not supported yet\n", __func__);
>
> *out_is_unlocked = true;
>
> diff --git a/include/avb_verify.h b/include/avb_verify.h
> index fb7ab23..9363ca5 100644
> --- a/include/avb_verify.h
> +++ b/include/avb_verify.h
> @@ -11,12 +11,23 @@
> #include <avb/libavb_ab.h>
> #include <mmc.h>
>
> -#define ALLOWED_BUF_ALIGN 8
> +#define AVB_MAX_ARGS 1024
> +#define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
> +#define VERITY_TABLE_OPT_LOGGING "ignore_corruption"
> +#define ALLOWED_BUF_ALIGN 8
> +
> +enum avb_boot_state {
> + AVB_GREEN,
> + AVB_YELLOW,
> + AVB_ORANGE,
> + AVB_RED,
> +};
>
> struct AvbOpsData {
> struct AvbOps ops;
> struct AvbABOps ab_ops;
> int mmc_dev;
> + enum avb_boot_state boot_state;
> };
>
> struct mmc_part {
> @@ -34,6 +45,12 @@ enum mmc_io_type {
> AvbOps *avb_ops_alloc(int boot_device);
> void avb_ops_free(AvbOps *ops);
>
> +char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state);
> +char *avb_set_enforce_verity(const char *cmdline);
> +char *avb_set_ignore_corruption(const char *cmdline);
> +
> +char *append_cmd_line(char *cmdline_orig, char *cmdline_new);
> +
> /**
> * ============================================================================
> * I/O helper inline functions
> --
> 2.7.4
>
More information about the U-Boot
mailing list