Skip to content

Commit

Permalink
PM: hibernate: disable when there are active secretmem users
Browse files Browse the repository at this point in the history
It is unsafe to allow saving of secretmem areas to the hibernation
snapshot as they would be visible after the resume and this essentially
will defeat the purpose of secret memory mappings.

Prevent hibernation whenever there are active secret memory users.

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Mike Rapoport <[email protected]>
Acked-by: David Hildenbrand <[email protected]>
Acked-by: James Bottomley <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Christopher Lameter <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Elena Reshetova <[email protected]>
Cc: Hagen Paul Pfeifer <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: "Kirill A. Shutemov" <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Michael Kerrisk <[email protected]>
Cc: Palmer Dabbelt <[email protected]>
Cc: Palmer Dabbelt <[email protected]>
Cc: Paul Walmsley <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Rick Edgecombe <[email protected]>
Cc: Roman Gushchin <[email protected]>
Cc: Shakeel Butt <[email protected]>
Cc: Shuah Khan <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tycho Andersen <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: kernel test robot <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
rppt authored and torvalds committed Jul 8, 2021
1 parent 1507f51 commit 9a436f8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
6 changes: 6 additions & 0 deletions include/linux/secretmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static inline bool page_is_secretmem(struct page *page)
}

bool vma_is_secretmem(struct vm_area_struct *vma);
bool secretmem_active(void);

#else

Expand All @@ -43,6 +44,11 @@ static inline bool page_is_secretmem(struct page *page)
return false;
}

static inline bool secretmem_active(void)
{
return false;
}

#endif /* CONFIG_SECRETMEM */

#endif /* _LINUX_SECRETMEM_H */
5 changes: 4 additions & 1 deletion kernel/power/hibernate.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/genhd.h>
#include <linux/ktime.h>
#include <linux/security.h>
#include <linux/secretmem.h>
#include <trace/events/power.h>

#include "power.h"
Expand Down Expand Up @@ -81,7 +82,9 @@ void hibernate_release(void)

bool hibernation_available(void)
{
return nohibernate == 0 && !security_locked_down(LOCKDOWN_HIBERNATION);
return nohibernate == 0 &&
!security_locked_down(LOCKDOWN_HIBERNATION) &&
!secretmem_active();
}

/**
Expand Down
15 changes: 15 additions & 0 deletions mm/secretmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ module_param_named(enable, secretmem_enable, bool, 0400);
MODULE_PARM_DESC(secretmem_enable,
"Enable secretmem and memfd_secret(2) system call");

static atomic_t secretmem_users;

bool secretmem_active(void)
{
return !!atomic_read(&secretmem_users);
}

static vm_fault_t secretmem_fault(struct vm_fault *vmf)
{
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
Expand Down Expand Up @@ -94,6 +101,12 @@ static const struct vm_operations_struct secretmem_vm_ops = {
.fault = secretmem_fault,
};

static int secretmem_release(struct inode *inode, struct file *file)
{
atomic_dec(&secretmem_users);
return 0;
}

static int secretmem_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long len = vma->vm_end - vma->vm_start;
Expand All @@ -116,6 +129,7 @@ bool vma_is_secretmem(struct vm_area_struct *vma)
}

static const struct file_operations secretmem_fops = {
.release = secretmem_release,
.mmap = secretmem_mmap,
};

Expand Down Expand Up @@ -202,6 +216,7 @@ SYSCALL_DEFINE1(memfd_secret, unsigned int, flags)
file->f_flags |= O_LARGEFILE;

fd_install(fd, file);
atomic_inc(&secretmem_users);
return fd;

err_put_fd:
Expand Down

0 comments on commit 9a436f8

Please sign in to comment.