於 日,2013-08-25 於 18:42 +0200,Pavel Machek 提到:
On Thu 2013-08-22 19:01:54, Lee, Chun-Yi wrote:
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 <jkosina@suse.cz> 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 -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org