Thread (66 messages) 66 messages, 5 authors, 2013-09-05

Re: [PATCH 15/18] Hibernate: adapt to UEFI secure boot with signature check

From: joeyli <jlee@suse.com>
Date: 2013-08-27 10:14:37
Also in: linux-crypto, linux-pm

於 日,2013-08-25 於 18:42 +0200,Pavel Machek 提到:
On Thu 2013-08-22 19:01:54, Lee, Chun-Yi wrote:
quoted
In current solution, the snapshot signature check used the RSA key-pair
that are generated by bootloader(e.g. shim) and pass the key-pair to
kernel through EFI variables. I choice to binding the snapshot
signature check mechanism with UEFI secure boot for provide stronger
protection of hibernate. Current behavior is following:

 + UEFI Secure Boot ON, Kernel found key-pair from shim:
   Will do the S4 signature check.

 + UEFI Secure Boot ON, Kernel didn't find key-pair from shim:
   Will lock down S4 function.

 + UEFI Secure Boot OFF
   Will NOT do the S4 signature check.
   Ignore any keys from bootloader.

v2:
Replace sign_key_data_loaded() by skey_data_available() to check sign key data
is available for hibernate.

Reviewed-by: Jiri Kosina <redacted>
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 kernel/power/hibernate.c |   36 +++++++++++++++++-
 kernel/power/main.c      |   11 +++++-
 kernel/power/snapshot.c  |   95 ++++++++++++++++++++++++++--------------------
 kernel/power/swap.c      |    4 +-
 kernel/power/user.c      |   11 +++++
 5 files changed, 112 insertions(+), 45 deletions(-)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index c545b15..0f19f3d 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -29,6 +29,7 @@
 #include <linux/ctype.h>
 #include <linux/genhd.h>
 #include <linux/key.h>
+#include <linux/efi.h>
 
 #include "power.h"
 
@@ -632,7 +633,14 @@ static void power_down(void)
 int hibernate(void)
 {
 	int error;
-	int skey_error;
+
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+	if (!capable(CAP_COMPROMISE_KERNEL) && !skey_data_available()) {
+#else
+	if (!capable(CAP_COMPROMISE_KERNEL)) {
+#endif
+		return -EPERM;
+	}
 
 	lock_system_sleep();
 	/* The snapshot device should not be opened while we're running */
@@ -799,6 +807,15 @@ static int software_resume(void)
 	if (error)
 		goto Unlock;
 
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+	if (!capable(CAP_COMPROMISE_KERNEL) && !wkey_data_available()) {
+#else
+	if (!capable(CAP_COMPROMISE_KERNEL)) {
+#endif
+		mutex_unlock(&pm_mutex);
+		return -EPERM;
+	}
+
 	/* The snapshot device should not be opened while we're running */
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
 		error = -EBUSY;
@@ -892,6 +909,15 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
 	int i;
 	char *start = buf;
 
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+	if (efi_enabled(EFI_SECURE_BOOT) && !skey_data_available()) {
+#else
+	if (efi_enabled(EFI_SECURE_BOOT)) {
+#endif
+		buf += sprintf(buf, "[%s]\n", "disabled");
+		return buf-start;
+	}
+
 	for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
 		if (!hibernation_modes[i])
 			continue;
@@ -926,6 +952,14 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
 	char *p;
 	int mode = HIBERNATION_INVALID;
 
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+	if (!capable(CAP_COMPROMISE_KERNEL) && !skey_data_available()) {
+#else
+	if (!capable(CAP_COMPROMISE_KERNEL)) {
+#endif
+		return -EPERM;
+	}
+
 	p = memchr(buf, '\n', n);
 	len = p ? p - buf : n;
 
You clearly need some helper function.
									Pavel
I will use a help function to replace those ifdef block.

Thanks for your suggestion!
Joey Lee
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help