[PATCH RFC] Add a lockdown_hibernate parameter

From: Kelvie Wong
Date: Mon Nov 13 2023 - 21:25:26 EST


This allows the user to tell the kernel that they know better (namely,
they secured their swap properly), and that it can enable hibernation.

I've been using this for about a year now, as it doesn't seem like
proper secure hibernation was going to be implemented back then, and
it's now been a year since I've been building my own kernels with this
patch, so getting this upstreamed would save some CO2 from me building
my own kernels every upgrade.

Some other not-me users have also tested the patch:

https://community.frame.work/t/guide-fedora-36-hibernation-with-enabled-secure-boot-and-full-disk-encryption-fde-decrypting-over-tpm2/25474/17

Signed-off-by: Kelvie Wong <kelvie@xxxxxxxxx>
---
Documentation/admin-guide/kernel-parameters.txt | 5 +++++
kernel/power/hibernate.c | 10 +++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 426fa892d311..54785faba9e0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2804,6 +2804,11 @@
to extract confidential information from the kernel
are also disabled.

+ lockdown_hibernate [HIBERNATION]
+ Enable hibernation even if lockdown is enabled. Enable this only if
+ your swap is encrypted and secured properly, as an attacker can
+ modify the kernel offline during hibernation.
+
locktorture.nreaders_stress= [KNL]
Set the number of locking read-acquisition kthreads.
Defaults to being automatically set based on the
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 89c71fce225d..2221c531d54c 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -36,6 +36,7 @@
#include "power.h"


+static int lockdown_hibernate;
static int nocompress;
static int noresume;
static int nohibernate;
@@ -82,7 +83,7 @@ void hibernate_release(void)
bool hibernation_available(void)
{
return nohibernate == 0 &&
- !security_locked_down(LOCKDOWN_HIBERNATION) &&
+ (lockdown_hibernate || !security_locked_down(LOCKDOWN_HIBERNATION)) &&
!secretmem_active() && !cxl_mem_active();
}

@@ -1340,6 +1341,12 @@ static int __init nohibernate_setup(char *str)
return 1;
}

+static int __init lockdown_hibernate_setup(char *str)
+{
+ lockdown_hibernate = 1;
+ return 1;
+}
+
__setup("noresume", noresume_setup);
__setup("resume_offset=", resume_offset_setup);
__setup("resume=", resume_setup);
@@ -1347,3 +1354,4 @@ __setup("hibernate=", hibernate_setup);
__setup("resumewait", resumewait_setup);
__setup("resumedelay=", resumedelay_setup);
__setup("nohibernate", nohibernate_setup);
+__setup("lockdown_hibernate", lockdown_hibernate_setup);
--
2.37.3