From 57bc385827e7c0e0c86f30bbfa2d48ca9505537e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Fri, 3 Dec 2021 14:18:31 +0100
Subject: [PATCH] mokutil: enable setting fallback verbosity and noreboot mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Having mokutil handle FALLBACK_VERBOSE and FB_NO_REBOOT variables eases
fallback debugging.

Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 data/mokutil  |  8 ++++++
 man/mokutil.1 | 10 +++++++
 src/mokutil.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 90 insertions(+), 1 deletion(-)

Index: mokutil-0.1.0/man/mokutil.1
===================================================================
--- mokutil-0.1.0.orig/man/mokutil.1
+++ mokutil-0.1.0/man/mokutil.1
@@ -36,6 +36,10 @@ mokutil \- utility to manipulate machine
 .br
 \fBmokutil\fR [--generate-hash=\fIpassword\fR | -g\fIpassword\fR]
 .br
+\fBmokutil\fR [--set-fallback-verbosity (\fItrue\fR | \fIfalse\fR)]
+.br
+\fBmokutil\fR [--set-fallback-noreboot (\fItrue\fR | \fIfalse\fR)]
+.br
 \fBmokutil\fR [--sbat]
 .br
 
@@ -93,6 +97,13 @@ Use the password hash from a specific fi
 .TP
 \fB--root-pw\fR
 Use the root password hash from /etc/shadow
+.TP
+\fB--set-fallback-verbosity\fR
+Set the FALLBACK_VERBOSE to make fallback more or less verbose
+.TP
+\fB--set-fallback-noreboot\fR
+Set the FB_NO_REBOOT to prevent fallback from automatically rebooting the system
+.TP
 \fB--sbat\fR
 List the entries in the Secure Boot Advanced Targeting store (SBAT)
 .TP
Index: mokutil-0.1.0/src/mokutil.c
===================================================================
--- mokutil-0.1.0.orig/src/mokutil.c
+++ mokutil-0.1.0/src/mokutil.c
@@ -43,6 +43,8 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0x
 #define RESET              0x2000
 #define GENERATE_PW_HASH   0x4000
 #define LIST_SBAT          (1 << 24)
+#define FB_VERBOSITY       (1 << 25)
+#define FB_NOREBOOT        (1 << 26)
 
 #define DEFAULT_CRYPT_METHOD SHA512_BASED
 #define DEFAULT_SALT_SIZE    SHA512_SALT_MAX
@@ -89,6 +91,8 @@ print_help ()
 	printf ("  --root-pw\t\t\t\tUse the root password\n");
 	printf ("           \t\t\t\t(Only valid with --import, --delete,\n");
 	printf ("           \t\t\t\t --password, and --reset)\n");
+	printf ("  --set-fallback-verbosity <true/false>\t\tSet the verbosity bit for fallback\n");
+	printf ("  --set-fallback-noreboot <true/false>\t\tPrevent fallback from automatically rebooting\n");
 	printf ("  --sbat\t\t\t\tList the entries in SBAT\n");
 }
 
@@ -1305,6 +1309,58 @@ print_var_content (const char *var_name,
 	return 0;
 }
 
+static int
+set_fallback_verbosity (const uint8_t verbosity)
+{
+	efi_variable_t var;
+
+	if (verbosity) {
+		var.Data = (uint8_t *)&verbosity;
+		var.DataSize = sizeof (verbosity);
+		var.VariableName = "FALLBACK_VERBOSE";
+
+		var.VendorGuid = SHIM_LOCK_GUID;
+		var.Attributes = EFI_VARIABLE_NON_VOLATILE
+			| EFI_VARIABLE_BOOTSERVICE_ACCESS
+			| EFI_VARIABLE_RUNTIME_ACCESS;
+
+		if (edit_variable (&var) != EFI_SUCCESS) {
+			fprintf (stderr, "Failed to set FALLBACK_VERBOSE\n");
+			return -1;
+		}
+	} else {
+		return test_and_delete_var ("FALLBACK_VERBOSE");
+	}
+
+	return 0;
+}
+
+static int
+set_fallback_noreboot (const uint8_t noreboot)
+{
+	efi_variable_t var;
+
+	if (noreboot) {
+		var.Data = (uint8_t *)&noreboot;
+		var.DataSize = sizeof (noreboot);
+		var.VariableName = "FB_NO_REBOOT";
+
+		var.VendorGuid = SHIM_LOCK_GUID;
+		var.Attributes = EFI_VARIABLE_NON_VOLATILE
+			| EFI_VARIABLE_BOOTSERVICE_ACCESS
+			| EFI_VARIABLE_RUNTIME_ACCESS;
+
+		if (edit_variable (&var) != EFI_SUCCESS) {
+			fprintf (stderr, "Failed to set FB_NO_REBOOT\n");
+			return -1;
+		}
+	} else {
+		return test_and_delete_var ("FB_NO_REBOOT");
+	}
+
+	return 0;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -1316,6 +1372,8 @@ main (int argc, char *argv[])
 	int c, i, f_ind, total = 0;
 	unsigned int command = 0;
 	int use_root_pw = 0;
+	uint8_t fb_verbosity = 0;
+	uint8_t fb_noreboot = 0;
 	int ret = -1;
 
 	while (1) {
@@ -1337,6 +1395,8 @@ main (int argc, char *argv[])
 			{"hash-file",          required_argument, 0, 'f'},
 			{"generate-hash",      optional_argument, 0, 'g'},
 			{"root-pw",            no_argument,       0, 'P'},
+			{"set-fallback-verbosity", required_argument, 0, 0  },
+			{"set-fallback-noreboot", required_argument, 0, 0  },
 			{"sbat",               no_argument,       0, 0  },
 			{0, 0, 0, 0}
 		};
@@ -1367,6 +1427,22 @@ main (int argc, char *argv[])
 				command |= SB_STATE;
 			} else if (strcmp (option, "reset") == 0) {
 				command |= RESET;
+			} else if (strcmp (option, "set-fallback-verbosity") == 0) {
+				command |= FB_VERBOSITY;
+				if (strcmp (optarg, "true") == 0)
+					fb_verbosity = 1;
+				else if (strcmp (optarg, "false") == 0)
+					fb_verbosity = 0;
+				else
+					command |= HELP;
+			} else if (strcmp (option, "set-fallback-noreboot") == 0) {
+				command |= FB_NOREBOOT;
+				if (strcmp (optarg, "true") == 0)
+					fb_noreboot = 1;
+				else if (strcmp (optarg, "false") == 0)
+					fb_noreboot = 0;
+				else
+					command |= HELP;
 			}  else if (strcmp (option, "sbat") == 0) {
 				command |= LIST_SBAT;
 			}
@@ -1494,6 +1570,12 @@ main (int argc, char *argv[])
 		case GENERATE_PW_HASH:
 			ret = generate_pw_hash (input_pw);
 			break;
+		case FB_VERBOSITY:
+			ret = set_fallback_verbosity (fb_verbosity);
+			break;
+		case FB_NOREBOOT:
+			ret = set_fallback_noreboot (fb_noreboot);
+			break;
 		case LIST_SBAT:
 			ret = print_var_content ("SbatLevelRT", SHIM_LOCK_GUID);
 			break;
