lkml.org 
[lkml]   [2021]   [May]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH v19 6/8] PM: hibernate: disable when there are active secretmem users
From
Date
On 13.05.21 20:47, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> 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.
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Christopher Lameter <cl@linux.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Elena Reshetova <elena.reshetova@intel.com>
> Cc: Hagen Paul Pfeifer <hagen@jauu.net>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Michael Kerrisk <mtk.manpages@gmail.com>
> Cc: Palmer Dabbelt <palmer@dabbelt.com>
> Cc: Palmer Dabbelt <palmerdabbelt@google.com>
> Cc: Paul Walmsley <paul.walmsley@sifive.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Cc: Roman Gushchin <guro@fb.com>
> Cc: Shakeel Butt <shakeelb@google.com>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Tycho Andersen <tycho@tycho.ws>
> Cc: Will Deacon <will@kernel.org>
> ---
> include/linux/secretmem.h | 6 ++++++
> kernel/power/hibernate.c | 5 ++++-
> mm/secretmem.c | 15 +++++++++++++++
> 3 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/secretmem.h b/include/linux/secretmem.h
> index e617b4afcc62..21c3771e6a56 100644
> --- a/include/linux/secretmem.h
> +++ b/include/linux/secretmem.h
> @@ -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
>
> @@ -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 */
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index da0b41914177..559acef3fddb 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -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"
> @@ -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();
> }
>
> /**
> diff --git a/mm/secretmem.c b/mm/secretmem.c
> index 1ae50089adf1..7c2499e4de22 100644
> --- a/mm/secretmem.c
> +++ b/mm/secretmem.c
> @@ -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;
> @@ -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;
> @@ -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,
> };
>
> @@ -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:
>

It looks a bit racy, but I guess we don't really care about these corner
cases.

Acked-by: David Hildenbrand <david@redhat.com>

--
Thanks,

David / dhildenb

\
 
 \ /
  Last update: 2021-05-14 11:27    [W:0.358 / U:0.480 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site