[PATCH v3 RESEND 3/4] PM: hibernate: permit encrypted snapshot device under lockdown
From: Sean Rhodes
Date: Thu Sep 17 2026 - 10:34:07 EST
Lockdown disables hibernation because restoring attacker-controlled image
data can modify kernel memory. Permit opening the userspace snapshot
device under lockdown when encrypted hibernation support is built, but
require encryption to be enabled before image data can be read or written
and before restore or power-off ioctls can proceed.
Tested on StarFighter MTL with lockdown enabled: encrypted uswsusp
hibernate and restore used the snapshot device path.
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
---
kernel/power/hibernate.c | 8 ++++++++
kernel/power/power.h | 1 +
kernel/power/user.c | 2 +-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index a95cb447a13a..0b8626bdf81a 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -114,6 +114,14 @@ bool hibernation_available(void)
!secretmem_active() && !cxl_mem_active();
}
+bool hibernation_snapshot_dev_available(void)
+{
+ return nohibernate == 0 &&
+ (!security_locked_down(LOCKDOWN_HIBERNATION) ||
+ IS_ENABLED(CONFIG_ENCRYPTED_HIBERNATION)) &&
+ !secretmem_active() && !cxl_mem_active();
+}
+
/**
* hibernation_set_ops - Set the global hibernate operations.
* @ops: Hibernation operations to use in subsequent hibernation transitions.
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 815c84c1e0dd..351b5f68bde3 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -168,6 +168,7 @@ extern int snapshot_image_loaded(struct snapshot_handle *handle);
extern bool hibernate_acquire(void);
extern void hibernate_release(void);
+bool hibernation_snapshot_dev_available(void);
extern sector_t alloc_swapdev_block(int swap);
bool swsusp_swap_range_allocated(int swap, loff_t pos, size_t count);
diff --git a/kernel/power/user.c b/kernel/power/user.c
index de41f590c98d..b8d3342f1548 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -184,7 +184,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
unsigned int sleep_flags;
int error;
- if (!hibernation_available())
+ if (!hibernation_snapshot_dev_available())
return -EPERM;
sleep_flags = lock_system_sleep();