Blob Blame History Raw
From aaf360b4b69f18e8c28458cd1eb92971b58618a9 Mon Sep 17 00:00:00 2001
From: "Lee, Chun-Yi" <jlee@suse.com>
Date: Tue, 7 Jul 2015 13:39:07 +0800
Subject: [PATCH v2 11/16] PM / hibernate: Avoid including hibernation key to
 hibernate image

Patch-mainline: Not yet, reviewing on linux-efi
References: fate#316350

The HMAC key should only resides in kernel memory space but not leak
to outside. To avoid including hibernation key in hibernate snapshot
image, this patch adds the checking block in the code for asking saveable
pages to make sure the key page should not marked as saveable.

Reviewed-by: Jiri Kosina <jkosina@suse.com>
Tested-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 arch/x86/power/hibernate_keys.c |   15 +++++++++++++++
 kernel/power/power.h            |    3 +++
 kernel/power/snapshot.c         |    6 ++++++
 3 files changed, 24 insertions(+)

--- a/arch/x86/power/hibernate_keys.c
+++ b/arch/x86/power/hibernate_keys.c
@@ -47,6 +47,21 @@ int get_hibernation_key(u8 **hkey)
 	return hibernation_keys->hkey_status;
 }
 
+
+bool swsusp_page_is_keys(struct page *page)
+{
+	bool ret = false;
+
+	if (!hibernation_keys || hibernation_keys->hkey_status)
+		return ret;
+
+	ret = (page_to_pfn(page) == page_to_pfn(virt_to_page(hibernation_keys)));
+	if (ret)
+		pr_info("PM: Avoid snapshot the page of hibernation key.\n");
+
+	return ret;
+}
+
 static int __init init_hibernation_keys(void)
 {
 	struct hibernation_keys *keys;
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -19,6 +19,9 @@ struct swsusp_info {
 #ifdef CONFIG_HIBERNATE_VERIFICATION
 /* arch/x86/power/hibernate_keys.c */
 extern int get_hibernation_key(u8 **hkey);
+extern bool swsusp_page_is_keys(struct page *page);
+#else
+static inline bool swsusp_page_is_keys(struct page *page) { return false; }
 #endif
 
 /* kernel/power/snapshot.c */
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1093,6 +1093,9 @@ static struct page *saveable_highmem_pag
 
 	BUG_ON(!PageHighMem(page));
 
+	if (swsusp_page_is_keys(page))
+		return NULL;
+
 	if (swsusp_page_is_forbidden(page) ||  swsusp_page_is_free(page) ||
 	    PageReserved(page))
 		return NULL;
@@ -1155,6 +1158,9 @@ static struct page *saveable_page(struct
 
 	BUG_ON(PageHighMem(page));
 
+	if (swsusp_page_is_keys(page))
+		return NULL;
+
 	if (swsusp_page_is_forbidden(page) || swsusp_page_is_free(page))
 		return NULL;