avb2.0: add boot states and dm-verity support
authorIgor Opaniuk <igor.opaniuk@linaro.org>
Sun, 3 Jun 2018 18:56:40 +0000 (21:56 +0300)
committerTom Rini <trini@konsulko.com>
Mon, 18 Jun 2018 17:55:13 +0000 (13:55 -0400)
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@linaro.org>
cmd/avb.c
common/avb_verify.c
include/avb_verify.h

index dd389cd..f045a0c 100644 (file)
--- 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;
@@ -249,10 +251,23 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag,
 
        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;
index a4de168..f9a00f8 100644 (file)
@@ -119,6 +119,137 @@ 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;
+
+       if (!str)
+               return -1;
+
+       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 +609,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 +633,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 +653,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;
 
index 428c69a..eaa60f5 100644 (file)
 #include <../lib/libavb/libavb.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;
        int mmc_dev;
+       enum avb_boot_state boot_state;
 };
 
 struct mmc_part {
@@ -33,6 +44,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