[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