diff mbox series

[v2,5/8] avb2.0: add boot states and dm-verity support

Message ID 1528052203-29689-6-git-send-email-igor.opaniuk@linaro.org
State Accepted
Commit 5d4fd8777337134dc1a1270f27569a9ccaece193
Headers show
Series Initial integration of AVB2.0 | expand

Commit Message

Igor Opaniuk June 3, 2018, 6:56 p.m. UTC
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            |  17 ++++++-
 common/avb_verify.c  | 137 +++++++++++++++++++++++++++++++++++++++++++++++++--
 include/avb_verify.h |  19 ++++++-
 3 files changed, 168 insertions(+), 5 deletions(-)

Comments

Tom Rini June 19, 2018, 6:40 p.m. UTC | #1
On Sun, Jun 03, 2018 at 09:56:40PM +0300, Igor Opaniuk 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@linaro.org>


Applied to u-boot/master, thanks!

-- 
Tom
diff mbox series

Patch

diff --git a/cmd/avb.c b/cmd/avb.c
index dd389cd..f045a0c 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;
@@ -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;
diff --git a/common/avb_verify.c b/common/avb_verify.c
index a4de168..f9a00f8 100644
--- a/common/avb_verify.c
+++ b/common/avb_verify.c
@@ -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;
 
diff --git a/include/avb_verify.h b/include/avb_verify.h
index 428c69a..eaa60f5 100644
--- a/include/avb_verify.h
+++ b/include/avb_verify.h
@@ -11,11 +11,22 @@ 
 #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