From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41781C4727D for ; Sat, 26 Sep 2020 02:37:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EBD1121741 for ; Sat, 26 Sep 2020 02:37:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1601087852; bh=YPO69aWTdb14eopjw3IMB0NZD0an594sLV/exej/sUs=; h=Date:From:To:Subject:Reply-To:List-ID:From; b=bxGomHvefpHH9doeu2GolSoqWXBtailCL9Pm8i/q0pOBol1JRSYVPF3XpYJ9i/IHd wEarcBqdftTjy5DmLEDk95Zck1H/zsiHuPNGfDAEUbkC7VZAGlMcpkU0TOJkl9MtHH WJSwLgQkUF3RqAxZJ33nBglzuoqYUOgW/TniWG1E= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728406AbgIZChb (ORCPT ); Fri, 25 Sep 2020 22:37:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:54490 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726210AbgIZChb (ORCPT ); Fri, 25 Sep 2020 22:37:31 -0400 Received: from X1 (unknown [104.245.68.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1EF9D20936; Sat, 26 Sep 2020 02:37:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1601087850; bh=YPO69aWTdb14eopjw3IMB0NZD0an594sLV/exej/sUs=; h=Date:From:To:Subject:From; b=IOzThrvg3ra7YzF216ZO0spowBjiMiyCtIoxmoX1aoYEO0AnH7A2VlPbYs+tUAEkN 4cTTjgdeZEiyMT0hvX6ffcbBKHnNdveNpt2hOvR7jzHosplzJ799Ab35fBRm+4/9ns E6Lpw5OAx48U+tXv8I9OVNlfpx8ccJD60d6DF0P8= Date: Fri, 25 Sep 2020 19:37:28 -0700 From: akpm@linux-foundation.org To: mm-commits@vger.kernel.org, willy@infradead.org, will@kernel.org, viro@zeniv.linux.org.uk, tycho@tycho.ws, tglx@linutronix.de, shuah@kernel.org, peterz@infradead.org, paul.walmsley@sifive.com, palmerdabbelt@google.com, palmer@dabbelt.com, mtk.manpages@gmail.com, mingo@redhat.com, mark.rutland@arm.com, luto@kernel.org, kirill@shutemov.name, jejb@linux.ibm.com, idan.yaniv@ibm.com, hpa@zytor.com, elena.reshetova@intel.com, david@redhat.com, dave.hansen@linux.intel.com, dan.j.williams@intel.com, cl@linux.com, catalin.marinas@arm.com, bp@alien8.de, arnd@arndb.de, rppt@linux.ibm.com Subject: [to-be-updated] mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas.patch removed from -mm tree Message-ID: <20200926023728.OGicz%akpm@linux-foundation.org> User-Agent: s-nail v14.9.10 Precedence: bulk Reply-To: linux-kernel@vger.kernel.org List-ID: X-Mailing-List: mm-commits@vger.kernel.org The patch titled Subject: mm: introduce memfd_secret system call to create "secret" memory areas has been removed from the -mm tree. Its filename was mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas.patch This patch was dropped because an updated version will be merged ------------------------------------------------------ From: Mike Rapoport Subject: mm: introduce memfd_secret system call to create "secret" memory areas Introduce "memfd_secret" system call with the ability to create memory areas visible only in the context of the owning process and not mapped not only to other processes but in the kernel page tables as well. The user will create a file descriptor using the memfd_secret() system call where flags supplied as a parameter to this system call will define the desired protection mode for the memory associated with that file descriptor. Currently there are two protection modes: * exclusive - the memory area is unmapped from the kernel direct map and it is present only in the page tables of the owning mm. * uncached - the memory area is present only in the page tables of the owning mm and it is mapped there as uncached. The "exclusive" mode is enabled implicitly and it is the default mode for memfd_secret(). The "uncached" mode requires architecture support and an architecture should opt-in for this mode using HAVE_SECRETMEM_UNCACHED configuration option. For instance, the following example will create an uncached mapping (error handling is omitted): fd = memfd_secret(SECRETMEM_UNCACHED); ftruncate(fd, MAP_SIZE); ptr = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); Link: https://lkml.kernel.org/r/20200924132904.1391-4-rppt@kernel.org Signed-off-by: Mike Rapoport Cc: Alexander Viro Cc: Andy Lutomirski Cc: Arnd Bergmann Cc: Borislav Petkov Cc: Catalin Marinas Cc: Christopher Lameter Cc: Dan Williams Cc: Dave Hansen Cc: David Hildenbrand Cc: Elena Reshetova Cc: "H. Peter Anvin" Cc: Idan Yaniv Cc: Ingo Molnar Cc: James Bottomley Cc: "Kirill A. Shutemov" Cc: Mark Rutland Cc: Matthew Wilcox Cc: Michael Kerrisk Cc: Palmer Dabbelt Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Peter Zijlstra Cc: Shuah Khan Cc: Thomas Gleixner Cc: Tycho Andersen Cc: Will Deacon Signed-off-by: Andrew Morton --- arch/Kconfig | 7 arch/x86/Kconfig | 1 include/uapi/linux/magic.h | 1 include/uapi/linux/secretmem.h | 8 kernel/sys_ni.c | 2 mm/Kconfig | 4 mm/Makefile | 1 mm/secretmem.c | 264 +++++++++++++++++++++++++++++++ 8 files changed, 288 insertions(+) --- a/arch/Kconfig~mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas +++ a/arch/Kconfig @@ -991,6 +991,13 @@ config HAVE_STATIC_CALL_INLINE bool depends on HAVE_STATIC_CALL +config HAVE_SECRETMEM_UNCACHED + bool + help + An architecture can select this if its semantics of non-cached + mappings can be used to prevent speculative loads and it is + useful for secret protection. + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" --- a/arch/x86/Kconfig~mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas +++ a/arch/x86/Kconfig @@ -222,6 +222,7 @@ config X86 select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_USER_RETURN_NOTIFIER select HAVE_GENERIC_VDSO + select HAVE_SECRETMEM_UNCACHED select HOTPLUG_SMT if SMP select IRQ_FORCED_THREADING select NEED_SG_DMA_LENGTH --- a/include/uapi/linux/magic.h~mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas +++ a/include/uapi/linux/magic.h @@ -97,5 +97,6 @@ #define DEVMEM_MAGIC 0x454d444d /* "DMEM" */ #define Z3FOLD_MAGIC 0x33 #define PPC_CMM_MAGIC 0xc7571590 +#define SECRETMEM_MAGIC 0x5345434d /* "SECM" */ #endif /* __LINUX_MAGIC_H__ */ --- /dev/null +++ a/include/uapi/linux/secretmem.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_SECRERTMEM_H +#define _UAPI_LINUX_SECRERTMEM_H + +/* secretmem operation modes */ +#define SECRETMEM_UNCACHED 0x1 + +#endif /* _UAPI_LINUX_SECRERTMEM_H */ --- a/kernel/sys_ni.c~mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas +++ a/kernel/sys_ni.c @@ -353,6 +353,8 @@ COND_SYSCALL(pkey_mprotect); COND_SYSCALL(pkey_alloc); COND_SYSCALL(pkey_free); +/* memfd_secret */ +COND_SYSCALL(memfd_secret); /* * Architecture specific weak syscall entries. --- a/mm/Kconfig~mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas +++ a/mm/Kconfig @@ -869,4 +869,8 @@ config ARCH_HAS_HUGEPD config MAPPING_DIRTY_HELPERS bool +config SECRETMEM + def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED + select GENERIC_ALLOCATOR + endmenu --- a/mm/Makefile~mm-introduce-memfd_secret-system-call-to-create-secret-memory-areas +++ a/mm/Makefile @@ -121,3 +121,4 @@ obj-$(CONFIG_MEMFD_CREATE) += memfd.o obj-$(CONFIG_MAPPING_DIRTY_HELPERS) += mapping_dirty_helpers.o obj-$(CONFIG_PTDUMP_CORE) += ptdump.o obj-$(CONFIG_PAGE_REPORTING) += page_reporting.o +obj-$(CONFIG_SECRETMEM) += secretmem.o --- /dev/null +++ a/mm/secretmem.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright IBM Corporation, 2020 + * + * Author: Mike Rapoport + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "internal.h" + +#undef pr_fmt +#define pr_fmt(fmt) "secretmem: " fmt + +/* + * Secret memory areas are always exclusive to owning mm and they are + * removed from the direct map. + */ +#ifdef CONFIG_HAVE_SECRETMEM_UNCACHED +#define SECRETMEM_MODE_MASK (SECRETMEM_UNCACHED) +#else +#define SECRETMEM_MODE_MASK (0x0) +#endif + +#define SECRETMEM_FLAGS_MASK SECRETMEM_MODE_MASK + +struct secretmem_ctx { + unsigned int mode; +}; + +static struct page *secretmem_alloc_page(gfp_t gfp) +{ + /* + * FIXME: use a cache of large pages to reduce the direct map + * fragmentation + */ + return alloc_page(gfp); +} + +static vm_fault_t secretmem_fault(struct vm_fault *vmf) +{ + struct address_space *mapping = vmf->vma->vm_file->f_mapping; + struct inode *inode = file_inode(vmf->vma->vm_file); + pgoff_t offset = vmf->pgoff; + unsigned long addr; + struct page *page; + int ret = 0; + + if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode)) + return vmf_error(-EINVAL); + + page = find_get_entry(mapping, offset); + if (!page) { + page = secretmem_alloc_page(vmf->gfp_mask); + if (!page) + return vmf_error(-ENOMEM); + + ret = add_to_page_cache(page, mapping, offset, vmf->gfp_mask); + if (unlikely(ret)) + goto err_put_page; + + ret = set_direct_map_invalid_noflush(page); + if (ret) + goto err_del_page_cache; + + addr = (unsigned long)page_address(page); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE); + + __SetPageUptodate(page); + + ret = VM_FAULT_LOCKED; + } + + vmf->page = page; + return ret; + +err_del_page_cache: + delete_from_page_cache(page); +err_put_page: + put_page(page); + return vmf_error(ret); +} + +static const struct vm_operations_struct secretmem_vm_ops = { + .fault = secretmem_fault, +}; + +static int secretmem_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct secretmem_ctx *ctx = file->private_data; + unsigned long len = vma->vm_end - vma->vm_start; + + if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) + return -EINVAL; + + if (mlock_future_check(vma->vm_mm, vma->vm_flags | VM_LOCKED, len)) + return -EAGAIN; + + if (ctx->mode & SECRETMEM_UNCACHED) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + vma->vm_ops = &secretmem_vm_ops; + vma->vm_flags |= VM_LOCKED; + + return 0; +} + +const struct file_operations secretmem_fops = { + .mmap = secretmem_mmap, +}; + +static bool secretmem_isolate_page(struct page *page, isolate_mode_t mode) +{ + return false; +} + +static int secretmem_migratepage(struct address_space *mapping, + struct page *newpage, struct page *page, + enum migrate_mode mode) +{ + return -EBUSY; +} + +static void secretmem_freepage(struct page *page) +{ + set_direct_map_default_noflush(page); +} + +static const struct address_space_operations secretmem_aops = { + .freepage = secretmem_freepage, + .migratepage = secretmem_migratepage, + .isolate_page = secretmem_isolate_page, +}; + +static struct vfsmount *secretmem_mnt; + +static struct file *secretmem_file_create(unsigned long flags) +{ + struct file *file = ERR_PTR(-ENOMEM); + struct secretmem_ctx *ctx; + struct inode *inode; + + inode = alloc_anon_inode(secretmem_mnt->mnt_sb); + if (IS_ERR(inode)) + return ERR_CAST(inode); + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + goto err_free_inode; + + file = alloc_file_pseudo(inode, secretmem_mnt, "secretmem", + O_RDWR, &secretmem_fops); + if (IS_ERR(file)) + goto err_free_ctx; + + mapping_set_unevictable(inode->i_mapping); + + inode->i_mapping->private_data = ctx; + inode->i_mapping->a_ops = &secretmem_aops; + + /* pretend we are a normal file with zero size */ + inode->i_mode |= S_IFREG; + inode->i_size = 0; + + file->private_data = ctx; + + ctx->mode = flags & SECRETMEM_MODE_MASK; + + return file; + +err_free_ctx: + kfree(ctx); +err_free_inode: + iput(inode); + return file; +} + +SYSCALL_DEFINE1(memfd_secret, unsigned long, flags) +{ + struct file *file; + int fd, err; + + /* make sure local flags do not confict with global fcntl.h */ + BUILD_BUG_ON(SECRETMEM_FLAGS_MASK & O_CLOEXEC); + + if (flags & ~(SECRETMEM_FLAGS_MASK | O_CLOEXEC)) + return -EINVAL; + + fd = get_unused_fd_flags(flags & O_CLOEXEC); + if (fd < 0) + return fd; + + file = secretmem_file_create(flags); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto err_put_fd; + } + + file->f_flags |= O_LARGEFILE; + + fd_install(fd, file); + return fd; + +err_put_fd: + put_unused_fd(fd); + return err; +} + +static void secretmem_evict_inode(struct inode *inode) +{ + struct secretmem_ctx *ctx = inode->i_private; + + truncate_inode_pages_final(&inode->i_data); + clear_inode(inode); + kfree(ctx); +} + +static const struct super_operations secretmem_super_ops = { + .evict_inode = secretmem_evict_inode, +}; + +static int secretmem_init_fs_context(struct fs_context *fc) +{ + struct pseudo_fs_context *ctx = init_pseudo(fc, SECRETMEM_MAGIC); + + if (!ctx) + return -ENOMEM; + ctx->ops = &secretmem_super_ops; + + return 0; +} + +static struct file_system_type secretmem_fs = { + .name = "secretmem", + .init_fs_context = secretmem_init_fs_context, + .kill_sb = kill_anon_super, +}; + +static int secretmem_init(void) +{ + int ret = 0; + + secretmem_mnt = kern_mount(&secretmem_fs); + if (IS_ERR(secretmem_mnt)) + ret = PTR_ERR(secretmem_mnt); + + return ret; +} +fs_initcall(secretmem_init); _ Patches currently in -mm which might be from rppt@linux.ibm.com are mm-account-pmd-tables-like-pte-tables-fix.patch kvm-ppc-book3s-hv-simplify-kvm_cma_reserve.patch dma-contiguous-simplify-cma_early_percent_memory.patch arm-xtensa-simplify-initialization-of-high-memory-pages.patch arm64-numa-simplify-dummy_numa_init.patch h8300-nds32-openrisc-simplify-detection-of-memory-extents.patch riscv-drop-unneeded-node-initialization.patch mircoblaze-drop-unneeded-numa-and-sparsemem-initializations.patch memblock-make-for_each_memblock_type-iterator-private.patch memblock-make-memblock_debug-and-related-functionality-private.patch memblock-reduce-number-of-parameters-in-for_each_mem_range.patch arch-mm-replace-for_each_memblock-with-for_each_mem_pfn_range.patch arch-drivers-replace-for_each_membock-with-for_each_mem_range.patch arch-drivers-replace-for_each_membock-with-for_each_mem_range-fix-2.patch x86-setup-simplify-initrd-relocation-and-reservation.patch x86-setup-simplify-reserve_crashkernel.patch memblock-remove-unused-memblock_mem_size.patch memblock-implement-for_each_reserved_mem_region-using-__next_mem_region.patch memblock-use-separate-iterators-for-memory-and-reserved-regions.patch mm-remove-unused-early_pfn_valid.patch arch-mm-wire-up-memfd_secret-system-call-were-relevant.patch mm-secretmem-use-pmd-size-pages-to-amortize-direct-map-fragmentation.patch secretmem-test-add-basic-selftest-for-memfd_secret2.patch