From patchwork Fri Dec 21 18:14:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740817 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 87929924 for ; Fri, 21 Dec 2018 18:15:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AD7B2835B for ; Fri, 21 Dec 2018 18:15:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6EE2A28628; Fri, 21 Dec 2018 18:15:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id CBD972835B for ; Fri, 21 Dec 2018 18:14:59 +0000 (UTC) Received: (qmail 30640 invoked by uid 550); 21 Dec 2018 18:14:58 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 30605 invoked from network); 21 Dec 2018 18:14:57 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=9pkoDpWnQ0hyqDvaxlvdmZrME9c2qqzlc2zOv6te5xY=; b=N2niqEomFo+rals4bkw3xGbTBjGwxa/HjF9TepnB4pLUjTMQIoZ7v9NVFAHvYtA9gY /0oYQRkwRCEM/u8qr8aLfkPZbFq08vKAZrJbeRw+uPsmd1krMueHpwqVSWjWPyHJzZaw PZNRYzHlOXJQisYA87u0/ENAQ4P71tLBmcdqbPDndtRNBd4/Iko2g/ZGDVNsdjKMAj6O HEe4/wIgfiQh4kQzYdNojImGEYlQXTiGQwU/CvMINRzDx+6hF2dWBiUbCqC8PVrSR4RO zs+3oyb3DLgLu8gImsLRxllVJm3T8bTtcMSk7ZqGUzsimoakWJXB9iCFE24/c/a4ekVm 7ZRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=9pkoDpWnQ0hyqDvaxlvdmZrME9c2qqzlc2zOv6te5xY=; b=MLUqPW2LLkl+2ZcBxLtgk7lklYh2WAAyhXhkVVruIEqYzmyCoWdMVVK6KtLU3Ugsup caBFkI8g79a03FeRfR10YTNu7LS03JKbTZUmJB/rd10/zs2MAJy0OPAlHihjrTYKiaWN Zt4H/1jf4wJju75KRCoI7ePKavXn9NHnKSkYRVqv1UAIA2t8oAYIIGCMkyfj6BavBH13 CF1nOmbeonHUoUNonIfp5W57ezEThu7/dAZfJ1mi5Yg/WisxiGHhwLHwVs37zDctFMXH 6t8PgTqhHt4QSlP7Mgm2hS/cymqwpm/654DasUgw2BU6KGSt7sYcCbSgdEUEogrlgZXd cs5g== X-Gm-Message-State: AJcUukcmuVaeUq/thO6I2AZc553ZuVv112avTu1y4jmzlwei0/CtDy7c x/fQN0ik/Jfr3ht9hI4IxsI= X-Google-Smtp-Source: AFSGD/XIkFyHzT2h0WZYCzCstedNVsVpCOdIZJXFreII8gK7lJaMNaWsCWFp0aHljWPuf+HZlBsPEQ== X-Received: by 2002:a2e:908b:: with SMTP id l11-v6mr2285752ljg.150.1545416086374; Fri, 21 Dec 2018 10:14:46 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 01/12] x86_64: memset_user() Date: Fri, 21 Dec 2018 20:14:12 +0200 Message-Id: <20181221181423.20455-2-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Create x86_64 specific version of memset for user space, based on clear_user(). This will be used for implementing wr_memset() in the __wr_after_init scenario, where write-rare variables have an alternate mapping for writing. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- arch/x86/include/asm/uaccess_64.h | 6 ++++ arch/x86/lib/usercopy_64.c | 54 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index a9d637bc301d..f194bfce4866 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -213,4 +213,10 @@ copy_user_handle_tail(char *to, char *from, unsigned len); unsigned long mcsafe_handle_tail(char *to, char *from, unsigned len); +unsigned long __must_check +memset_user(void __user *mem, int c, unsigned long len); + +unsigned long __must_check +__memset_user(void __user *mem, int c, unsigned long len); + #endif /* _ASM_X86_UACCESS_64_H */ diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 1bd837cdc4b1..84f8f8a20b30 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -9,6 +9,60 @@ #include #include +/* + * Memset Userspace + */ + +unsigned long __memset_user(void __user *addr, int c, unsigned long size) +{ + long __d0; + unsigned long pattern = 0; + int i; + + for (i = 0; i < 8; i++) + pattern = (pattern << 8) | (0xFF & c); + might_fault(); + /* no memory constraint: gcc doesn't know about this memory */ + stac(); + asm volatile( + " movq %[val], %%rdx\n" + " testq %[size8],%[size8]\n" + " jz 4f\n" + "0: mov %%rdx,(%[dst])\n" + " addq $8,%[dst]\n" + " decl %%ecx ; jnz 0b\n" + "4: movq %[size1],%%rcx\n" + " testl %%ecx,%%ecx\n" + " jz 2f\n" + "1: movb %%dl,(%[dst])\n" + " incq %[dst]\n" + " decl %%ecx ; jnz 1b\n" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: lea 0(%[size1],%[size8],8),%[size8]\n" + " jmp 2b\n" + ".previous\n" + _ASM_EXTABLE_UA(0b, 3b) + _ASM_EXTABLE_UA(1b, 2b) + : [size8] "=&c"(size), [dst] "=&D" (__d0) + : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr), + [val] "ri"(pattern) + : "rdx"); + + clac(); + return size; +} +EXPORT_SYMBOL(__memset_user); + +unsigned long memset_user(void __user *to, int c, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + return __memset_user(to, c, n); + return n; +} +EXPORT_SYMBOL(memset_user); + + /* * Zero Userspace */ From patchwork Fri Dec 21 18:14:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740821 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3958D924 for ; Fri, 21 Dec 2018 18:15:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D2E12835B for ; Fri, 21 Dec 2018 18:15:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 20BD728618; Fri, 21 Dec 2018 18:15:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 022A32835B for ; Fri, 21 Dec 2018 18:15:06 +0000 (UTC) Received: (qmail 31975 invoked by uid 550); 21 Dec 2018 18:15:00 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 31868 invoked from network); 21 Dec 2018 18:14:59 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=02CsOTWqtwZzPMlweM9pS6XE1OnLE/PPqdTJz4OZtoU=; b=C/bllgwWcelpTykNWYi39BnaATo8lpq89ch1ugnwfkYPRnVxve0wGvexjuxUPMzDoo 5Jpl5b0JUZ4ZL/39R1AR2j4X3k6ukiq9RlxTBcEzcGXXAV++v3Za4nKsdMqOIzA9BnLM FYYV6EhXu7gS7jQm20h6QR7xCxqPqLFD8gIyXunzOdhwh2+LhS6sZVyX0ahZHFfkn3Xw sGSbMTE95/rO31tGYeJBOFMCsqpicf6WF5vlojY4Bfno1gSEaX5smNWCKjXFGXXiAutn S0s+m5efoXLUf0pB106ZUBJIrPyvf1cnpu48uQJzohHGLMXY7JXthKhEMa1N9dvbpmSr FT6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=02CsOTWqtwZzPMlweM9pS6XE1OnLE/PPqdTJz4OZtoU=; b=gCzQ50/t2cvu/q77NYhTjGWdwFwWldfV7CllVa2yanaABdpR3FanxZQaH2iTBHLX4V 0SIWSm3n30ROILMHM/4uscLfGlLKrKC3OLjfZvy21GcYWX6kycrdRyGpM4P4pG1IG9HZ 0KaP++1B2usN4CI0ZzQXV62Qp3DnASa2mKRtItYjLnmrFUhcEVyPn/vxKNzZM3C8QIu6 D7aJ2x+IvuBZ9mBsOEkDcVIDqtCZ9TSYky/rd09B0MH2ZJ25G8Xf+XPjRBUwPgZgCNCJ G9C9JMi/5RpeSACehWdBHw4fNE2qV52Nx9rpWMBoeka3L5AG6RkN3kv/VRjdtOIZqRs3 1F+g== X-Gm-Message-State: AJcUukcmaxanlSC5X9rsGhsRFyJJlRJi/GFCha20nnnosfyMfdzef3VL FUmcpjV26Uzh6hwXQx2z+g/suXvjuMY= X-Google-Smtp-Source: ALg8bN6ADTRPD4oTDrtkd5En5+bsIvKrP+5XCjbqDTL4+Lh9yRDACXYcUUsznsEdhYFvH6hg+L2VRA== X-Received: by 2002:a2e:5b1d:: with SMTP id p29-v6mr2252747ljb.176.1545416088161; Fri, 21 Dec 2018 10:14:48 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 02/12] __wr_after_init: linker section and label Date: Fri, 21 Dec 2018 20:14:13 +0200 Message-Id: <20181221181423.20455-3-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Introduce a section and a label for statically allocated write rare data. The label is named "__wr_after_init". As the name implies, after the init phase is completed, this section will be modifiable only by invoking write rare functions. The section must take up a set of full pages. To activate both section and label, the arch must set CONFIG_ARCH_HAS_PRMEM Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- arch/Kconfig | 15 +++++++++++++++ include/asm-generic/vmlinux.lds.h | 25 +++++++++++++++++++++++++ include/linux/cache.h | 21 +++++++++++++++++++++ init/main.c | 2 ++ 4 files changed, 63 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index e1e540ffa979..8668ffec8098 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -802,6 +802,21 @@ config VMAP_STACK the stack to map directly to the KASAN shadow map using a formula that is incorrect if the stack is in vmalloc space. +config ARCH_HAS_PRMEM + def_bool n + help + architecture specific symbol stating that the architecture provides + a back-end function for the write rare operation. + +config PRMEM + bool "Write protect critical data that doesn't need high write speed." + depends on ARCH_HAS_PRMEM + default y + help + If the architecture supports it, statically allocated data which + has been selected for hardening becomes (mostly) read-only. + The selection happens by labelling the data "__wr_after_init". + config ARCH_OPTIONAL_KERNEL_RWX def_bool n diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 3d7a6a9c2370..ddb1fd608490 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -311,6 +311,30 @@ KEEP(*(__jump_table)) \ __stop___jump_table = .; +/* + * Allow architectures to handle wr_after_init data on their + * own by defining an empty WR_AFTER_INIT_DATA. + * However, it's important that pages containing WR_RARE data do not + * hold anything else, to avoid both accidentally unprotecting something + * that is supposed to stay read-only all the time and also to protect + * something else that is supposed to be writeable all the time. + */ +#ifndef WR_AFTER_INIT_DATA +#ifdef CONFIG_PRMEM +#define WR_AFTER_INIT_DATA(align) \ + . = ALIGN(PAGE_SIZE); \ + __start_wr_after_init = .; \ + . = ALIGN(align); \ + *(.data..wr_after_init) \ + . = ALIGN(PAGE_SIZE); \ + __end_wr_after_init = .; \ + . = ALIGN(align); +#else +#define WR_AFTER_INIT_DATA(align) \ + . = ALIGN(align); +#endif +#endif + /* * Allow architectures to handle ro_after_init data on their * own by defining an empty RO_AFTER_INIT_DATA. @@ -332,6 +356,7 @@ __start_rodata = .; \ *(.rodata) *(.rodata.*) \ RO_AFTER_INIT_DATA /* Read only after init */ \ + WR_AFTER_INIT_DATA(align) /* wr after init */ \ KEEP(*(__vermagic)) /* Kernel version magic */ \ . = ALIGN(8); \ __start___tracepoints_ptrs = .; \ diff --git a/include/linux/cache.h b/include/linux/cache.h index 750621e41d1c..09bd0b9284b6 100644 --- a/include/linux/cache.h +++ b/include/linux/cache.h @@ -31,6 +31,27 @@ #define __ro_after_init __attribute__((__section__(".data..ro_after_init"))) #endif +/* + * __wr_after_init is used to mark objects that cannot be modified + * directly after init (i.e. after mark_rodata_ro() has been called). + * These objects become effectively read-only, from the perspective of + * performing a direct write, like a variable assignment. + * However, they can be altered through a dedicated function. + * It is intended for those objects which are occasionally modified after + * init, however they are modified so seldomly, that the extra cost from + * the indirect modification is either negligible or worth paying, for the + * sake of the protection gained. + */ +#ifndef __wr_after_init +#ifdef CONFIG_PRMEM +#define __wr_after_init \ + __attribute__((__section__(".data..wr_after_init"))) +#else +#define __wr_after_init +#endif +#endif + + #ifndef ____cacheline_aligned #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) #endif diff --git a/init/main.c b/init/main.c index a461150adfb1..a36f2e54f937 100644 --- a/init/main.c +++ b/init/main.c @@ -498,6 +498,7 @@ void __init __weak thread_stack_cache_init(void) void __init __weak mem_encrypt_init(void) { } void __init __weak poking_init(void) { } +void __init __weak wr_poking_init(void) { } bool initcall_debug; core_param(initcall_debug, initcall_debug, bool, 0644); @@ -734,6 +735,7 @@ asmlinkage __visible void __init start_kernel(void) delayacct_init(); poking_init(); + wr_poking_init(); check_bugs(); acpi_subsystem_init(); From patchwork Fri Dec 21 18:14:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740827 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DAFEF924 for ; Fri, 21 Dec 2018 18:15:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB0C42835B for ; Fri, 21 Dec 2018 18:15:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BEDA828618; Fri, 21 Dec 2018 18:15:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id A2A552835B for ; Fri, 21 Dec 2018 18:15:16 +0000 (UTC) Received: (qmail 32128 invoked by uid 550); 21 Dec 2018 18:15:01 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 32082 invoked from network); 21 Dec 2018 18:15:01 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=IC72E1SkxQby2tnvUgxalWUUCvjmMLY+yVrjL3hsqg8=; b=DqfsEH5L9YLdOJEXEYum6nwamDbHwKJwJCpeilO+Exni09zMXlLazjQWwG6UxGeyFW cthZ8/pTG4OViX9K/JQWfmJtS9F33LP1hb71YBXNsYDRjNxCpqV8NAzPvx7VOuAH5Tsc LPXPMnueI2EidByLqVwQ22AzvLQ144Ldw2HPEGliQyeXceXtPW1uaP/Sg86LlkmwCPHw /WOXCOYsw5cASKVRpV1s+hAEGzNAktCNUUXk5jWzgAJ/4jfpfwYuqnCr8CnsDS11dTI1 Ntel2Ew+lNIzH4pDzhUWw44FbLcUVoKFuI4LeX7oBViWiQnjx4Wqptqvm437EweXZB72 NKwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=IC72E1SkxQby2tnvUgxalWUUCvjmMLY+yVrjL3hsqg8=; b=QUJcTwGZNo4pgBbdbZLgDhgH4wJO84hngWltaNvfJ+s2P+1WaNlEt+d01zbyb1iib0 5L2JMZW/9iDHox2ym+GyANsA0ocEjOssFV2zIvtog++SBvWXMdPe2k1Lg90gIc5hukm+ wKfySfbxf+rzdVQmxeW+LDQgp+rB5Gql5oHIFevo2PJEabURkqOq/816J1Rv/t+P8IrW wU+2BBfH62Blhb6fT7FNqiR6avUk2JKrR163HfsGupHnYwzeIKMIaPDbEW6ZeSktON6/ X9p8djoDGa0inJJmdrcfGjNPNj6MjZMXzRGJCZDLszJzuBdY9sNpEXBgFZwUyJ58yS0n RbKA== X-Gm-Message-State: AA+aEWaskZ/6mfWO066yvK75/DQbKL0bon/bKf/24hgV2iqimC6Ngthr tismjzbKyQ2viA4tcO50/Ls= X-Google-Smtp-Source: AFSGD/UxlqHZez0NWd/HSVJmkToecB7S72thDSg2Cw/dydhEx7i1lDETl2T5I7D9XKZozHyTtVweIQ== X-Received: by 2002:a2e:4746:: with SMTP id u67-v6mr2238745lja.142.1545416089950; Fri, 21 Dec 2018 10:14:49 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 03/12] __wr_after_init: generic functionality Date: Fri, 21 Dec 2018 20:14:14 +0200 Message-Id: <20181221181423.20455-4-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP The patch provides: - the generic part of the write rare functionality for static data, based on code from Matthew Wilcox - the dummy functionality, in case an arch doesn't support write rare or the functionality is disabled The basic functions are: - wr_memset(): write rare counterpart of memset() - wr_memcpy(): write rare counterpart of memcpy() - wr_assign(): write rare counterpart of the assignment ('=') operator - wr_rcu_assign_pointer(): write rare counterpart of rcu_assign_pointer() Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- include/linux/prmem.h | 106 ++++++++++++++++++++++++++++++++++++++++++ mm/Makefile | 1 + mm/prmem.c | 97 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 include/linux/prmem.h create mode 100644 mm/prmem.c diff --git a/include/linux/prmem.h b/include/linux/prmem.h new file mode 100644 index 000000000000..12c1d0d1cb78 --- /dev/null +++ b/include/linux/prmem.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * prmem.h: Header for memory protection library + * + * (C) Copyright 2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + * + * Support for: + * - statically allocated write rare data + */ + +#ifndef _LINUX_PRMEM_H +#define _LINUX_PRMEM_H + +#include +#include +#include + + +/** + * memtst() - test len bytes starting at p to match the c value + * @p: beginning of the memory to test + * @c: byte to compare against + * @len: amount of bytes to test + * + * Returns 0 on success, non-zero otherwise. + */ +static inline int memtst(void *p, int c, __kernel_size_t len) +{ + __kernel_size_t i; + + for (i = 0; i < len; i++) { + u8 d = *(i + (u8 *)p) - (u8)c; + + if (unlikely(d)) + return d; + } + return 0; +} + + +#ifndef CONFIG_PRMEM + +static inline void *wr_memset(void *p, int c, __kernel_size_t len) +{ + return memset(p, c, len); +} + +static inline void *wr_memcpy(void *p, const void *q, __kernel_size_t size) +{ + return memcpy(p, q, size); +} + +#define wr_assign(var, val) ((var) = (val)) +#define wr_rcu_assign_pointer(p, v) rcu_assign_pointer(p, v) + +#else + +#include +#include +#include +#include + +#include + +void *wr_memset(void *p, int c, __kernel_size_t len); +void *wr_memcpy(void *p, const void *q, __kernel_size_t size); + +/** + * wr_assign() - sets a write-rare variable to a specified value + * @var: the variable to set + * @val: the new value + * + * Returns: the variable + * + * Note: it might be possible to optimize this, to use wr_memset in some + * cases (maybe with NULL?). + */ + +#define wr_assign(var, val) ({ \ + typeof(var) tmp = (typeof(var))val; \ + \ + wr_memcpy(&var, &tmp, sizeof(var)); \ + var; \ +}) + +/** + * wr_rcu_assign_pointer() - initialize a pointer in rcu mode + * @p: the rcu pointer - it MUST be aligned to a machine word + * @v: the new value + * + * Returns the value assigned to the rcu pointer. + * + * It is provided as macro, to match rcu_assign_pointer() + * The rcu_assign_pointer() is implemented as equivalent of: + * + * smp_mb(); + * WRITE_ONCE(); + */ +#define wr_rcu_assign_pointer(p, v) ({ \ + smp_mb(); \ + wr_assign(p, v); \ + p; \ +}) +#endif +#endif diff --git a/mm/Makefile b/mm/Makefile index d210cc9d6f80..ef3867c16ce0 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_SPARSEMEM) += sparse.o obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o obj-$(CONFIG_SLOB) += slob.o obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o +obj-$(CONFIG_PRMEM) += prmem.o obj-$(CONFIG_KSM) += ksm.o obj-$(CONFIG_PAGE_POISONING) += page_poison.o obj-$(CONFIG_SLAB) += slab.o diff --git a/mm/prmem.c b/mm/prmem.c new file mode 100644 index 000000000000..e1c1be3a1171 --- /dev/null +++ b/mm/prmem.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * prmem.c: Memory Protection Library + * + * (C) Copyright 2017-2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + */ + +#include +#include +#include +#include +#include +#include +#include + +__ro_after_init bool wr_ready; + +/* + * The following two variables are statically allocated by the linker + * script at the the boundaries of the memory region (rounded up to + * multiples of PAGE_SIZE) reserved for __wr_after_init. + */ +extern long __start_wr_after_init; +extern long __end_wr_after_init; +static unsigned long start = (unsigned long)&__start_wr_after_init; +static unsigned long end = (unsigned long)&__end_wr_after_init; + +static inline bool is_wr_after_init(void *p, __kernel_size_t size) +{ + unsigned long low = (unsigned long)p; + unsigned long high = low + size; + + return likely(start <= low && high <= end); +} + +/** + * wr_memcpy() - copyes size bytes from q to p + * @p: beginning of the memory to write to + * @q: beginning of the memory to read from + * @size: amount of bytes to copy + * + * Returns pointer to the destination + * + * The architecture code must provide: + * void __wr_enable(wr_state_t *state) + * void *__wr_addr(void *addr) + * void *__wr_memcpy(void *p, const void *q, __kernel_size_t size) + * void __wr_disable(wr_state_t *state) + */ +void *wr_memcpy(void *p, const void *q, __kernel_size_t size) +{ + wr_state_t wr_state; + void *wr_poking_addr = __wr_addr(p); + + if (WARN_ONCE(!wr_ready, "No writable mapping available") || + WARN_ONCE(!is_wr_after_init(p, size), "Invalid WR range.")) + return p; + + local_irq_disable(); + __wr_enable(&wr_state); + __wr_memcpy(wr_poking_addr, q, size); + __wr_disable(&wr_state); + local_irq_enable(); + return p; +} + +/** + * wr_memset() - sets len bytes of the destination p to the c value + * @p: beginning of the memory to write to + * @c: byte to replicate + * @len: amount of bytes to copy + * + * Returns pointer to the destination + * + * The architecture code must provide: + * void __wr_enable(wr_state_t *state) + * void *__wr_addr(void *addr) + * void *__wr_memset(void *p, int c, __kernel_size_t len) + * void __wr_disable(wr_state_t *state) + */ +void *wr_memset(void *p, int c, __kernel_size_t len) +{ + wr_state_t wr_state; + void *wr_poking_addr = __wr_addr(p); + + if (WARN_ONCE(!wr_ready, "No writable mapping available") || + WARN_ONCE(!is_wr_after_init(p, len), "Invalid WR range.")) + return p; + + local_irq_disable(); + __wr_enable(&wr_state); + __wr_memset(wr_poking_addr, c, len); + __wr_disable(&wr_state); + local_irq_enable(); + return p; +} From patchwork Fri Dec 21 18:14:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740831 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A3C186C5 for ; Fri, 21 Dec 2018 18:15:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 978722835B for ; Fri, 21 Dec 2018 18:15:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B78E28618; Fri, 21 Dec 2018 18:15:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id A5C56284AA for ; Fri, 21 Dec 2018 18:15:26 +0000 (UTC) Received: (qmail 32354 invoked by uid 550); 21 Dec 2018 18:15:03 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 32305 invoked from network); 21 Dec 2018 18:15:03 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=Us5fQxnqAuf6nDTBJO2Qb2w31hoygG1FpkEKlSmx1Kw=; b=HGWfQjb5vbSEU703D7GDZF8gnrJ6CfP1TS1iPmRhSDLGjMliWP2OTU4t9dcTDDLFqv eDAU+7nNdwfcfoz6oYXjJL+HmL0C7ymB9ShJsMj23VqimbB2jkRvrjm8zuQ48p+Nfr75 ZoN6joq84uIn/psO+3Xg9u/0iXRyuQynvLmv/HtqwPCYoNAWC5Faa76BZyDT9FID2Vfu dqlkXt4qfXEYfLfc8I/aX6w3fTxt+HeG3t0yKQFDxfLBtruTGAPQ/XtAuVw0DefC7wLn CshGs3iZ+b8H51siPqXn+F0ztDMm4FEfvmDc8DP/V0wU19fqjPIHsEMvhcM4ZSk9hHIX btxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=Us5fQxnqAuf6nDTBJO2Qb2w31hoygG1FpkEKlSmx1Kw=; b=c0NVjfs0Jk5BDFLEFfiojgaDivbFwhy5/WNK/cAwFAt1URPYoB1xXVn+QXBbTbOveK BUWVzf8yia328RzFay4ACPNqisUTJzJ78FwGlV/F5hIdBeMuE4K51nDMNgOLVG4sxglT K6bEOZ/rmAuILoZ9G6otbfhH+nZkMsZpZAc8L42aqKX36r22rtEm7rTBnR+jFtEAfuE8 k3d+P+vPZHsg4xZcYnNPsFVJeuk1URz7S9arI5Dq+OZK+Dp2VyZOLgBZD+ePzbpqduRO MvExHbruMhsvX2u/gVSFmCK/+54GtCB8gHARajXROeEsUX3Durz+Bs3UsYKzbaCP8fbF abjw== X-Gm-Message-State: AA+aEWZIHSAYLJxANkbFNjgrn9FG7E0kI6zJvQ9BU1p8z+cxdD1+XoQa SSdh2E9/PxL7+w77OBcTkxs= X-Google-Smtp-Source: AFSGD/XRk3ffVjosi0KOa8ubOE0z0coXuuRA/SrFAZt3Qg8nlBRGeL4XEqjStoml5nY+Fgm+PFWoDQ== X-Received: by 2002:a19:1994:: with SMTP id 142mr2105273lfz.134.1545416091776; Fri, 21 Dec 2018 10:14:51 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 04/12] __wr_after_init: debug writes Date: Fri, 21 Dec 2018 20:14:15 +0200 Message-Id: <20181221181423.20455-5-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP After each write operation, confirm that it was successful, otherwise generate a warning. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- mm/Kconfig.debug | 8 ++++++++ mm/prmem.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug index 9a7b8b049d04..b10305cfac3c 100644 --- a/mm/Kconfig.debug +++ b/mm/Kconfig.debug @@ -94,3 +94,11 @@ config DEBUG_RODATA_TEST depends on STRICT_KERNEL_RWX ---help--- This option enables a testcase for the setting rodata read-only. + +config DEBUG_PRMEM + bool "Verify each write rare operation." + depends on PRMEM + default n + help + After any write rare operation, compares the data written with the + value provided by the caller. diff --git a/mm/prmem.c b/mm/prmem.c index e1c1be3a1171..51f6776e2515 100644 --- a/mm/prmem.c +++ b/mm/prmem.c @@ -61,6 +61,9 @@ void *wr_memcpy(void *p, const void *q, __kernel_size_t size) __wr_enable(&wr_state); __wr_memcpy(wr_poking_addr, q, size); __wr_disable(&wr_state); +#ifdef CONFIG_DEBUG_PRMEM + VM_WARN_ONCE(memcmp(p, q, size), "Failed %s()", __func__); +#endif local_irq_enable(); return p; } @@ -92,6 +95,9 @@ void *wr_memset(void *p, int c, __kernel_size_t len) __wr_enable(&wr_state); __wr_memset(wr_poking_addr, c, len); __wr_disable(&wr_state); +#ifdef CONFIG_DEBUG_PRMEM + VM_WARN_ONCE(memtst(p, c, len), "Failed %s()", __func__); +#endif local_irq_enable(); return p; } From patchwork Fri Dec 21 18:14:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740837 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E1B436C5 for ; Fri, 21 Dec 2018 18:15:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3D1E28426 for ; Fri, 21 Dec 2018 18:15:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C72CD28618; Fri, 21 Dec 2018 18:15:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id AB5A328426 for ; Fri, 21 Dec 2018 18:15:36 +0000 (UTC) Received: (qmail 32625 invoked by uid 550); 21 Dec 2018 18:15:05 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 32547 invoked from network); 21 Dec 2018 18:15:05 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=SN1YxRssqD/qbsJs6cWB56zoRuTrhLbtpCLtQvrTRuc=; b=TKdyKx/jrCPmAFRDV+JRiJANdImKAj933DMPS306pGi86XGkwj+0veYOqtcDmcyrjO vCfsX0EjPqV6JxEspMuCD7syOFu+fW7Ls0bgV1b4ZlTcTyIi5Oql5zNbSuc+80jK+/VX DM/4H8lprBVKz14tLSiADp5ICDkz9mVWmG/oMRH2xA0HOSQ6dNu953TqUVZjoQMNoDru 8FUS4oIGexrnmUsUPtj5ID/wr0hQgkpGKK+v8UuNNqz65pIaMEGbkr9wNg/hB4jMcz59 55PPj9akWYr8I0WhAzAG2xKK3oAvQD03wecwMctx3PGb9u8gNaL91wY0bxv5f9mXqxAo e80w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=SN1YxRssqD/qbsJs6cWB56zoRuTrhLbtpCLtQvrTRuc=; b=BJDZeYRAKC/Cd3ck5hqaB6eIW9EAKp3jqPhuy8PhspEJ2I9PiDQIR9lkGXpdX774Yv ONSSzefqrLQfAES5XCEtyclRPX092s03LImYxX7gx7JOnc3MXRZ6QH3UgE5wp8Shkmt5 IHCSoqIAKxBP9hqp8CBEsuDhHGXwSuHxLR9Pm0q0hlhTpuEyMcYl2RFyYPbxsIH+4ujl oCjy13J5VY86AwdfeoB0lgtKzQsh80npSm+hP/axqEqHPLId1SLtvCjcwoY8gE0Gq5x6 NHVD5HgWngR4tSMHm1TMmI3qEYBYfMSjMes2JLTs9MCxTIg4ehFvuNnHxiyazIE0Dh2a /MWQ== X-Gm-Message-State: AJcUukdG2QwWsnNPXb0ZqkJPxuejyT5OdyzDiqftsu2nl1EyBBQggDb5 ey4ZSH0uyNcx4AeZch2pipA= X-Google-Smtp-Source: ALg8bN6yuIckmNbKpfr+n67Or7uaJ2oFluosJDTSIQkUgvEiIqLM5ThHxUlnxLGzEbhgxJM4/tnQfw== X-Received: by 2002:a2e:98c9:: with SMTP id s9-v6mr1937913ljj.166.1545416094071; Fri, 21 Dec 2018 10:14:54 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 05/12] __wr_after_init: x86_64: __wr_op Date: Fri, 21 Dec 2018 20:14:16 +0200 Message-Id: <20181221181423.20455-6-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Architecture-specific implementation of the core write rare operation. The implementation is based on code from Andy Lutomirski and Nadav Amit for patching the text on x86 [here goes reference to commits, once merged] The modification of write protected data is done through an alternate mapping of the same pages, as writable. This mapping is persistent, but active only for a core that is performing a write rare operation. And only for the duration of said operation. Local interrupts are disabled, while the alternate mapping is active. In theory, it could introduce a non-predictable delay, in a preemptible system, however the amount of data to be altered is likely to be far smaller than a page. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- arch/x86/Kconfig | 1 + arch/x86/include/asm/prmem.h | 72 ++++++++++++++++++++++++++++++++++++ arch/x86/mm/Makefile | 2 + arch/x86/mm/prmem.c | 69 ++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 arch/x86/include/asm/prmem.h create mode 100644 arch/x86/mm/prmem.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8689e794a43c..e5e4fc4fa5c2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -32,6 +32,7 @@ config X86_64 select SWIOTLB select X86_DEV_DMA_OPS select ARCH_HAS_SYSCALL_WRAPPER + select ARCH_HAS_PRMEM # # Arch settings diff --git a/arch/x86/include/asm/prmem.h b/arch/x86/include/asm/prmem.h new file mode 100644 index 000000000000..e1f09f881351 --- /dev/null +++ b/arch/x86/include/asm/prmem.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * prmem.h: Header for memory protection library + * + * (C) Copyright 2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + * + * Support for: + * - statically allocated write rare data + */ + +#ifndef _ASM_X86_PRMEM_H +#define _ASM_X86_PRMEM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef temporary_mm_state_t wr_state_t; + +extern __ro_after_init struct mm_struct *wr_poking_mm; +extern __ro_after_init unsigned long wr_poking_base; + +static inline void *__wr_addr(void *addr) +{ + return (void *)(wr_poking_base + (unsigned long)addr); +} + +static inline void __wr_enable(wr_state_t *state) +{ + *state = use_temporary_mm(wr_poking_mm); +} + +static inline void __wr_disable(wr_state_t *state) +{ + unuse_temporary_mm(*state); +} + + +/** + * __wr_memset() - sets len bytes of the destination p to the c value + * @p: beginning of the memory to write to + * @c: byte to replicate + * @len: amount of bytes to copy + * + * Returns pointer to the destination + */ +static inline void *__wr_memset(void *p, int c, __kernel_size_t len) +{ + return (void *)memset_user((void __user *)p, (u8)c, len); +} + +/** + * __wr_memcpy() - copyes size bytes from q to p + * @p: beginning of the memory to write to + * @q: beginning of the memory to read from + * @size: amount of bytes to copy + * + * Returns pointer to the destination + */ +static inline void *__wr_memcpy(void *p, const void *q, __kernel_size_t size) +{ + return (void *)copy_to_user((void __user *)p, q, size); +} + +#endif diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 4b101dd6e52f..66652de1e2c7 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -53,3 +53,5 @@ obj-$(CONFIG_PAGE_TABLE_ISOLATION) += pti.o obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt.o obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_identity.o obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_boot.o + +obj-$(CONFIG_PRMEM) += prmem.o diff --git a/arch/x86/mm/prmem.c b/arch/x86/mm/prmem.c new file mode 100644 index 000000000000..f4b36baa2f19 --- /dev/null +++ b/arch/x86/mm/prmem.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * prmem.c: Memory Protection Library + * + * (C) Copyright 2017-2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + */ + +#include +#include +#include +#include +#include +#include + +extern __ro_after_init bool wr_ready; +__ro_after_init struct mm_struct *wr_poking_mm; +__ro_after_init unsigned long wr_poking_base; + +/* + * The following two variables are statically allocated by the linker + * script at the the boundaries of the memory region (rounded up to + * multiples of PAGE_SIZE) reserved for __wr_after_init. + */ +extern long __start_wr_after_init; +extern long __end_wr_after_init; + +struct mm_struct *copy_init_mm(void); +void __init wr_poking_init(void) +{ + unsigned long start = (unsigned long)&__start_wr_after_init; + unsigned long end = (unsigned long)&__end_wr_after_init; + unsigned long i; + + wr_poking_mm = copy_init_mm(); + if (WARN_ONCE(!wr_poking_mm, "No alternate mapping available.")) + return; + + /* + * Place 64TB of kernel address space within 128TB of user address + * space, at a random page aligned offset. + */ + wr_poking_base = (((unsigned long)kaslr_get_random_long("WR Poke")) & + PAGE_MASK) % (64 * _BITUL(40)); + + /* Create alternate mapping for the entire wr_after_init range. */ + for (i = start; i < end; i += PAGE_SIZE) { + struct page *page; + spinlock_t *ptl; + pte_t pte; + pte_t *ptep; + unsigned long wr_poking_addr; + + page = virt_to_page(i); + if (WARN_ONCE(!page, "WR memory without physical page")) + return; + wr_poking_addr = i + wr_poking_base; + + /* The lock is not needed, but avoids open-coding. */ + ptep = get_locked_pte(wr_poking_mm, wr_poking_addr, &ptl); + if (WARN_ONCE(!ptep, "No pte for writable mapping")) + return; + + pte = mk_pte(page, PAGE_KERNEL); + set_pte_at(wr_poking_mm, wr_poking_addr, ptep, pte); + spin_unlock(ptl); + } + wr_ready = true; +} From patchwork Fri Dec 21 18:14:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 00FB76C5 for ; Fri, 21 Dec 2018 18:15:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E915528426 for ; Fri, 21 Dec 2018 18:15:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCF99284AA; Fri, 21 Dec 2018 18:15:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id C830328622 for ; Fri, 21 Dec 2018 18:15:48 +0000 (UTC) Received: (qmail 1147 invoked by uid 550); 21 Dec 2018 18:15:08 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1068 invoked from network); 21 Dec 2018 18:15:07 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=y4zotDQYnZoXB9lfg1fC2W7czb+qE54ZRjKDYZQbGrM=; b=SvsaISUsENLTRerxTlrw5WngUCL6xcuf+y6j/r5ybSpTEfxaevKrsab709fKKhBFHj bDwmZRFgmlGlLH6FjZIZscR0mARSzL5Yc1Hymyod01ulZ++YoZYQqgmNdt5hGgCy/c1w dOBT1TON7MOsOs6Xw7MVbfxdS7EHIQYmGSXAmKQBDdENjV/u+AOBJ2y2A59gz4QamBCP UTifq3MQpLnaFdW5Xk4MLjGbO5nBEo9pGRwBG+W6PIBX76n7iZh9k2R9oNkzAxmSHaKA Z19GApJN2rFbLKVpY9/VsZ+zfN78gSapfg+d5LN8SNYSOESPzDlqQaFJ+a0L0WMvu1B/ svYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=y4zotDQYnZoXB9lfg1fC2W7czb+qE54ZRjKDYZQbGrM=; b=D+6sGn/o/wdnoBirSoIA4C8d4LK1B48BAdR68RUAvUXFhgiOLY6HVjvwTPVE4972dN 2kSpMVFgRlJWub6h7R8bU86uaBXLuieSI3+pdn1F0ze6fltDOpgSa1iR83yqsEjHORDC OeRt2twq92m8rF7r/qGnT/RzKBokO1cGE/wVHX5kVPwHKT7R04qsQdXVX1ji58IKi/tV 7A0i+F8VCT7r3bv5+skbapYzPkrceaih6abvWGTEoQc5e16oYCvx0fnfObNCQdiie4M8 tbNM831zIsISEsuHOCvpBy94wcY2cxr7x+W6l2rduYlWyQQNPPFtxiLmtcaM26990x7d N7bw== X-Gm-Message-State: AA+aEWZcMu0g2TANb+HH5pRQyW+j2uDswfUEF4SsLAaWb+j2MYDcauah P5m8OrXhMinoUwMdEnzwi5U= X-Google-Smtp-Source: AFSGD/UUw4QOTr1Fz5pqLC5tPgrFCIm78stVTJm1s66btznV4xeiArrlcZYeL5woLgX/8UrqetsuTw== X-Received: by 2002:a19:a60c:: with SMTP id p12mr2115400lfe.63.1545416096496; Fri, 21 Dec 2018 10:14:56 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 06/12] __wr_after_init: Documentation: self-protection Date: Fri, 21 Dec 2018 20:14:17 +0200 Message-Id: <20181221181423.20455-7-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Update the self-protection documentation, to mention also the use of the __wr_after_init attribute. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- Documentation/security/self-protection.rst | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Documentation/security/self-protection.rst b/Documentation/security/self-protection.rst index f584fb74b4ff..df2614bc25b9 100644 --- a/Documentation/security/self-protection.rst +++ b/Documentation/security/self-protection.rst @@ -84,12 +84,14 @@ For variables that are initialized once at ``__init`` time, these can be marked with the (new and under development) ``__ro_after_init`` attribute. -What remains are variables that are updated rarely (e.g. GDT). These -will need another infrastructure (similar to the temporary exceptions -made to kernel code mentioned above) that allow them to spend the rest -of their lifetime read-only. (For example, when being updated, only the -CPU thread performing the update would be given uninterruptible write -access to the memory.) +Others, which are statically allocated, but still need to be updated +rarely, can be marked with the ``__wr_after_init`` attribute. + +The update mechanism must avoid exposing the data to rogue alterations +during the update. For example, only the CPU thread performing the update +would be given uninterruptible write access to the memory. + +Currently there is no protection available for data allocated dynamically. Segregation of kernel memory from userspace memory ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From patchwork Fri Dec 21 18:14:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740853 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 08FA06C5 for ; Fri, 21 Dec 2018 18:16:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F160028426 for ; Fri, 21 Dec 2018 18:16:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E50EF28618; Fri, 21 Dec 2018 18:16:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 12A5228426 for ; Fri, 21 Dec 2018 18:16:00 +0000 (UTC) Received: (qmail 1394 invoked by uid 550); 21 Dec 2018 18:15:10 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1320 invoked from network); 21 Dec 2018 18:15:10 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=FDryqu5ur4j9ePg/wc9MnpTPYVkBg8AjJFLLJs3gfA8=; b=loRWo9kckttxn0cbJ+fMhQo8mYzlWi1+DZ1LXwFHcvwUSOVJ7CH068lDje4y/JF8Rm 4KOSZXWkx+GDi83Ss3j76Km/WDo3QRA8iGTHbvMD1tBfIvX/IpsjoNyU60bgIC7H6aNc 0kBRzwFWNpYFLT2X6pm/bNv3LhJUf+HMOG+dIa/LB5yvNOXBi7Ls8K0Ar0gdU8qKJGun N3+2efRoBPjH04D5aCWvEDNEiR8FxJXj9Y0Ng1Hstx4puvluHFXXOSSJ+qFnFNo4fQdC eA9q1xhmUFd5GVFJy0cmj2ZHDEO+vtXqkZ+C292gQrBJc+4K3eR4TBgWTZ4XrLWVP2gV mZEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=FDryqu5ur4j9ePg/wc9MnpTPYVkBg8AjJFLLJs3gfA8=; b=nadDbdvnd7+NY4qCYBmo7Pvq1Jaz5rNlhjs78x9GBXiwFMADUj20UYVbNFBI1PUIF6 Gn7yMrmB5FAN6UwyFm1G0PVMinImhtwAlg5n/PjSoi7TGhzThrxU4LAj+2gmB+dj5FS7 BjpCMXDYGeV+SG1ns9jbVvzn/8vGZ/WyUrfjjR0xfgT9hSPo2WTqXdNGGddn78MQuGdO XNl2lq7hhimTozZ4u5EpLmHXTODT+ZVTXXztslnvmsxBcrOszdnB8m1UO6YqRnicEzPx i81EUa7M2l524l4ML62+U1OAnrwvjgSGlbCGZzEbCuCcJhoiHrCe2x65TU5qbI/+OWo0 4h+A== X-Gm-Message-State: AA+aEWYQyfRIRO1oRIbszCciyLLKSCLN9t0/xXFSFtsg36kXrJIxCnCu SmF4E8+x7eN4aa00jhGFyNA= X-Google-Smtp-Source: AFSGD/VCXWhv1t5F5g9bAmEpbvcLcqmHx5RI8DK/pE5oqUo9y/6mbZGVq6pEeFsgUHszWM65/sjQlg== X-Received: by 2002:a19:c4cc:: with SMTP id u195mr1960679lff.141.1545416098906; Fri, 21 Dec 2018 10:14:58 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 07/12] __wr_after_init: lkdtm test Date: Fri, 21 Dec 2018 20:14:18 +0200 Message-Id: <20181221181423.20455-8-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Verify that trying to modify a variable with the __wr_after_init attribute will cause a crash. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- drivers/misc/lkdtm/core.c | 3 +++ drivers/misc/lkdtm/lkdtm.h | 3 +++ drivers/misc/lkdtm/perms.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 2837dc77478e..73c34b17c433 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -155,6 +155,9 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(ACCESS_USERSPACE), CRASHTYPE(WRITE_RO), CRASHTYPE(WRITE_RO_AFTER_INIT), +#ifdef CONFIG_PRMEM + CRASHTYPE(WRITE_WR_AFTER_INIT), +#endif CRASHTYPE(WRITE_KERN), CRASHTYPE(REFCOUNT_INC_OVERFLOW), CRASHTYPE(REFCOUNT_ADD_OVERFLOW), diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h index 3c6fd327e166..abba2f52ffa6 100644 --- a/drivers/misc/lkdtm/lkdtm.h +++ b/drivers/misc/lkdtm/lkdtm.h @@ -38,6 +38,9 @@ void lkdtm_READ_BUDDY_AFTER_FREE(void); void __init lkdtm_perms_init(void); void lkdtm_WRITE_RO(void); void lkdtm_WRITE_RO_AFTER_INIT(void); +#ifdef CONFIG_PRMEM +void lkdtm_WRITE_WR_AFTER_INIT(void); +#endif void lkdtm_WRITE_KERN(void); void lkdtm_EXEC_DATA(void); void lkdtm_EXEC_STACK(void); diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c index 53b85c9d16b8..f681730aa652 100644 --- a/drivers/misc/lkdtm/perms.c +++ b/drivers/misc/lkdtm/perms.c @@ -9,6 +9,7 @@ #include #include #include +#include #include /* Whether or not to fill the target memory area with do_nothing(). */ @@ -27,6 +28,10 @@ static const unsigned long rodata = 0xAA55AA55; /* This is marked __ro_after_init, so it should ultimately be .rodata. */ static unsigned long ro_after_init __ro_after_init = 0x55AA5500; +/* This is marked __wr_after_init, so it should be in .rodata. */ +static +unsigned long wr_after_init __wr_after_init = 0x55AA5500; + /* * This just returns to the caller. It is designed to be copied into * non-executable memory regions. @@ -104,6 +109,28 @@ void lkdtm_WRITE_RO_AFTER_INIT(void) *ptr ^= 0xabcd1234; } +#ifdef CONFIG_PRMEM + +void lkdtm_WRITE_WR_AFTER_INIT(void) +{ + unsigned long *ptr = &wr_after_init; + + /* + * Verify we were written to during init. Since an Oops + * is considered a "success", a failure is to just skip the + * real test. + */ + if ((*ptr & 0xAA) != 0xAA) { + pr_info("%p was NOT written during init!?\n", ptr); + return; + } + + pr_info("attempting bad wr_after_init write at %p\n", ptr); + *ptr ^= 0xabcd1234; +} + +#endif + void lkdtm_WRITE_KERN(void) { size_t size; @@ -200,4 +227,6 @@ void __init lkdtm_perms_init(void) /* Make sure we can write to __ro_after_init values during __init */ ro_after_init |= 0xAA; + /* Make sure we can write to __wr_after_init during __init */ + wr_after_init |= 0xAA; } From patchwork Fri Dec 21 18:14:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740857 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2BA58924 for ; Fri, 21 Dec 2018 18:16:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1FF8D28622 for ; Fri, 21 Dec 2018 18:16:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1430628632; Fri, 21 Dec 2018 18:16:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 3469B28628 for ; Fri, 21 Dec 2018 18:16:15 +0000 (UTC) Received: (qmail 1575 invoked by uid 550); 21 Dec 2018 18:15:13 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1514 invoked from network); 21 Dec 2018 18:15:12 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=vgb7J+uzu72a1nLgAIDJQpmIZYI0IWGcwJEvrx3eHk8=; b=kUeoKzL4DU9YWPEF1gNBKSCW0fL9CgdXq6jjpoupxnO4uLElST2H3S+SZCQgWimXXO YZMohIUO3dmUaPEpq05kR5+UYbdP8y+AIjfcy75gu+74W7d1pcqGXzRoIbVh/NgpQ4Hu XlT/e25pZJJetrF/oy9iRTDdIkBHVWZRayJtOBqc9NF0MTUYxKeUsVGasOcHzSVmNawK taKuwvPiPWuqWrhRKsjrXcBQPTXp8K6wjHW5mb0ZzblTCCVZfJb5fhn+NIqfncqQu0zm 0/IE8fGk5PL2rlOOPxS0vZLGHddhfFG0tPSDSKOTrDWp6euS3mJKoxmuscDdf7TiCAgY X65w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=vgb7J+uzu72a1nLgAIDJQpmIZYI0IWGcwJEvrx3eHk8=; b=rt25IiaeK2asfVfhXNNoYlVT6YWuQvuUwM7KTFlw6iok8EgOhfcc8e45vOj14tAFPe iIy/J15bcXoanhPPD/CuXbX4suuQq8Rh5yMZYUop0L2TwyzVhJXEbdqbiPmoek6tE/p5 nzm3fBs7R4AkVlaY8Pk5CVe/DKfyaCgncktb9ElgGKPzO3D8f3KcqdCfedCw2I0z4Vtq walLa+GDAMeF+Hq/zUNf99cY3R63Dov0hME/yCrm0Qhr/tMFRhT9XpN94aJerN30rUU4 WVU4f27PtzHpD3pLjgywtUe1EX9P3TPvMGdhsIuyl0rmDBv0/eG+R/h1N3a1ilGl0iyB 9rKQ== X-Gm-Message-State: AA+aEWYrGEbHJRVpMELc7MYyhK4BvkAFfS/1B5Hj1/gLuK6+xtP3DGGP ew6eNEYUXz/zKMTn5mQKY/g= X-Google-Smtp-Source: AFSGD/XswW5dKjiUGmh9wa+v9T60QYxp3Cs4xb9Q4fBCeW4KdXwqXRGKpf7tFOWWuwHHCYc03cVqMQ== X-Received: by 2002:a2e:21a9:: with SMTP id h41-v6mr2233605lji.103.1545416101435; Fri, 21 Dec 2018 10:15:01 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 08/12] rodata_test: refactor tests Date: Fri, 21 Dec 2018 20:14:19 +0200 Message-Id: <20181221181423.20455-9-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Refactor the test cases, in preparation for using them also for testing __wr_after_init memory, when available. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- mm/rodata_test.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/mm/rodata_test.c b/mm/rodata_test.c index d908c8769b48..e1349520b436 100644 --- a/mm/rodata_test.c +++ b/mm/rodata_test.c @@ -14,44 +14,52 @@ #include #include -static const int rodata_test_data = 0xC3; +#define INIT_TEST_VAL 0xC3 -void rodata_test(void) +static const int rodata_test_data = INIT_TEST_VAL; + +static bool test_data(char *data_type, const int *data, + unsigned long start, unsigned long end) { - unsigned long start, end; int zero = 0; /* test 1: read the value */ /* If this test fails, some previous testrun has clobbered the state */ - if (!rodata_test_data) { - pr_err("test 1 fails (start data)\n"); - return; + if (*data != INIT_TEST_VAL) { + pr_err("%s: test 1 fails (init data value)\n", data_type); + return false; } /* test 2: write to the variable; this should fault */ - if (!probe_kernel_write((void *)&rodata_test_data, - (void *)&zero, sizeof(zero))) { - pr_err("test data was not read only\n"); - return; + if (!probe_kernel_write((void *)data, (void *)&zero, sizeof(zero))) { + pr_err("%s: test data was not read only\n", data_type); + return false; } /* test 3: check the value hasn't changed */ - if (rodata_test_data == zero) { - pr_err("test data was changed\n"); - return; + if (*data != INIT_TEST_VAL) { + pr_err("%s: test data was changed\n", data_type); + return false; } /* test 4: check if the rodata section is PAGE_SIZE aligned */ - start = (unsigned long)__start_rodata; - end = (unsigned long)__end_rodata; if (start & (PAGE_SIZE - 1)) { - pr_err("start of .rodata is not page size aligned\n"); - return; + pr_err("%s: start of data is not page size aligned\n", + data_type); + return false; } if (end & (PAGE_SIZE - 1)) { - pr_err("end of .rodata is not page size aligned\n"); - return; + pr_err("%s: end of data is not page size aligned\n", + data_type); + return false; } + pr_info("%s tests were successful", data_type); + return true; +} - pr_info("all tests were successful\n"); +void rodata_test(void) +{ + test_data("rodata", &rodata_test_data, + (unsigned long)&__start_rodata, + (unsigned long)&__end_rodata); } From patchwork Fri Dec 21 18:14:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740863 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C1CF56C5 for ; Fri, 21 Dec 2018 18:16:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B57FB28426 for ; Fri, 21 Dec 2018 18:16:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A97B428618; Fri, 21 Dec 2018 18:16:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id C347D28426 for ; Fri, 21 Dec 2018 18:16:28 +0000 (UTC) Received: (qmail 1794 invoked by uid 550); 21 Dec 2018 18:15:15 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1721 invoked from network); 21 Dec 2018 18:15:14 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=hKpBmvKhY62YcE+qk2JyFeoOHJdEVTVCpq3mJ7wKHeo=; b=P/5eitQzqF4I/oTbSibobHwdzXYLEAMNbcNPfzS3a+ykbj4p7coiugUW2F9rjhhWMm lsNPk+KqhR4DNi7n4YQ0kjs7Hs/SgxhRaox/StG8MhP71NOi8+e3TtzbjmB19jA/2erO D1y8WK3jRyhpp8TdwUQv12RC02VyzLYGSD3rsfMZvW7goTHwYSCO6SmBy4GXZ0BuOa11 RbKHrcsnPGoXvCQgHf47Vp8mmIlUEp5jwiXap9+Z0uadOJtZti8Z/5aspb3g9vpmjCuE lKXA6AazVT+48O79fX+xuYZAoJVE5lK4GhgfGVWRtbwUwyRsRiB64G/B57fD3b0NkLNj 8nDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=hKpBmvKhY62YcE+qk2JyFeoOHJdEVTVCpq3mJ7wKHeo=; b=m0Ga8fJMB3p4iElta/jyLC02OQ4BEHTR2GhZnmuS84gfbpbSxUgG/XUUY28yNbQHRO XeAv5rtnZHhPDaqxl+y4jx4dKMHZvCaXIzhtNsucYdKblFx5dUQUBJIAvAMOcud951MS NIfvvLOcQNNAuU4pj6PPHZFewYNTlvi4N/3gsUSqbgZItBqBtJb2kCJtbWW+8FRblQBX 6eWFG+ruHwwGCCznQ560EfFfCKsvVUv0qQ8/Ruu+FZbn8NkOTKHh6T8+RQNOK4lZtCES zEHdqxq0GzNr9Ti6dU41Vaa3O0QLaavzXzGVimb768vpgZ6fF3WsWwxajQ7/QLaiXi4J pAGg== X-Gm-Message-State: AA+aEWaM7kRXNhLtT84lLN2+NNOJ/lFu3tgXF93YVsKOTcTEvZ9vb29E gylhdTYuPTjkzCaOZttI9gw= X-Google-Smtp-Source: AFSGD/W1G6Tq7n+hJWkNQlncfqgelqo0DV4gS71OAhO90oATObuU+4gfeMRLnUh0qrb9WRHlqlsVGQ== X-Received: by 2002:a19:2106:: with SMTP id h6mr1979270lfh.29.1545416103579; Fri, 21 Dec 2018 10:15:03 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 09/12] rodata_test: add verification for __wr_after_init Date: Fri, 21 Dec 2018 20:14:20 +0200 Message-Id: <20181221181423.20455-10-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP The write protection of the __wr_after_init data can be verified with the same methodology used for const data. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- mm/rodata_test.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/mm/rodata_test.c b/mm/rodata_test.c index e1349520b436..a669cf9f5a61 100644 --- a/mm/rodata_test.c +++ b/mm/rodata_test.c @@ -16,8 +16,23 @@ #define INIT_TEST_VAL 0xC3 +/* + * Note: __ro_after_init data is, for every practical effect, equivalent to + * const data, since they are even write protected at the same time; there + * is no need for separate testing. + * __wr_after_init data, otoh, is altered also after the write protection + * takes place and it cannot be exploitable for altering more permanent + * data. + */ + static const int rodata_test_data = INIT_TEST_VAL; +#ifdef CONFIG_PRMEM +static int wr_after_init_test_data __wr_after_init = INIT_TEST_VAL; +extern long __start_wr_after_init; +extern long __end_wr_after_init; +#endif + static bool test_data(char *data_type, const int *data, unsigned long start, unsigned long end) { @@ -59,7 +74,13 @@ static bool test_data(char *data_type, const int *data, void rodata_test(void) { - test_data("rodata", &rodata_test_data, - (unsigned long)&__start_rodata, - (unsigned long)&__end_rodata); + if (!test_data("rodata", &rodata_test_data, + (unsigned long)&__start_rodata, + (unsigned long)&__end_rodata)) + return; +#ifdef CONFIG_PRMEM + test_data("wr after init data", &wr_after_init_test_data, + (unsigned long)&__start_wr_after_init, + (unsigned long)&__end_wr_after_init); +#endif } From patchwork Fri Dec 21 18:14:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740865 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 194316C5 for ; Fri, 21 Dec 2018 18:16:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0C73B28426 for ; Fri, 21 Dec 2018 18:16:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F257C28618; Fri, 21 Dec 2018 18:16:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id D4D8528426 for ; Fri, 21 Dec 2018 18:16:40 +0000 (UTC) Received: (qmail 1990 invoked by uid 550); 21 Dec 2018 18:15:17 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1894 invoked from network); 21 Dec 2018 18:15:16 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=Aq308heKsk4esUtukI9Gf9fzo9QCFgtk6ZobMHavXuA=; b=IRZ+PyBuxLaMslt65054k/kYU+s6Lx4w0X2OysMfSTyO41jhjmWgxTFGHtjyQ+KZr4 w/HUG2V9Vk8dOcm1pqIsGS53R0nxnYgaSv6NZ3MoEoX/E1QDatB0JLr4N5vj3Fvppvor hCCePLAOY147qrKlxJ3LwlvB6bl167jmFzii0cT5+me9jty91p++RXSs9DjhigrN674h nm2kyyk7NRrUo5nAjy3R6lnishwEuKRoaRRdd45ioq3et6t/YlIx/N1NvAnzY24H7BB8 ZzUlKdl4g0sHWU4V1pL7qAnuA8szUKCICBLuXyeNK3U94W4ZJynrNRrhd5I2AXNHp4X3 l8tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=Aq308heKsk4esUtukI9Gf9fzo9QCFgtk6ZobMHavXuA=; b=nXD7hMo5vX8ZMHROMFHF5CYt6/8DhATfpbpB5NjoZuHc2QPsI0CKC7tnq4NzWbsjfP W5xWXgyXZZfI2reFwNh0xxfZL7iljnFgA8rvLSMcDdLQ5MwMMFDX0QnHyR1uPRKTKVGB +lJntGqd/61EX/ucc4Zc+Oi1L+Uc1nySrwu59O3jbYsiZmJG6KCI9AL1BHOnxyBYNJvy 9lcREJAUDg1Niiha8lyb/kWmgo0p5O4IrJq7BdsN74M9FpyLCqRyKYGAkouvezJ4N/wq tozPbduYONyydrQD6HLXVbsoavJvHm8NB+PnIX5tZ+Yj02WdM8W8h79j3VqgLEQVkXwg kv3w== X-Gm-Message-State: AA+aEWbkK64/DwbRCAIIAbs3xt0mX26WVlSG76s2E3AN8xDNgZg9e2by M3xIKgFsFBTGg75q1O7i8Ns= X-Google-Smtp-Source: AFSGD/UTO2+5Y57wxsVOt0L54LzOA6GkKnWKM/unPMbnjSXwDXmTroHSZC9Qk0m9UrkBOXswSYZzSA== X-Received: by 2002:a2e:914b:: with SMTP id q11-v6mr2230934ljg.164.1545416105497; Fri, 21 Dec 2018 10:15:05 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 10/12] __wr_after_init: test write rare functionality Date: Fri, 21 Dec 2018 20:14:21 +0200 Message-Id: <20181221181423.20455-11-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Set of test cases meant to confirm that the write rare functionality works as expected. It can be optionally compiled as module. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- mm/Kconfig.debug | 8 +++ mm/Makefile | 1 + mm/test_write_rare.c | 135 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 mm/test_write_rare.c diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug index b10305cfac3c..ae018e56c4e4 100644 --- a/mm/Kconfig.debug +++ b/mm/Kconfig.debug @@ -102,3 +102,11 @@ config DEBUG_PRMEM help After any write rare operation, compares the data written with the value provided by the caller. + +config DEBUG_PRMEM_TEST + tristate "Run self test for statically allocated protected memory" + depends on PRMEM + default n + help + Tries to verify that the protection for statically allocated memory + works correctly and that the memory is effectively protected. diff --git a/mm/Makefile b/mm/Makefile index ef3867c16ce0..8de1d468f4e7 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o obj-$(CONFIG_SLOB) += slob.o obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o obj-$(CONFIG_PRMEM) += prmem.o +obj-$(CONFIG_DEBUG_PRMEM_TEST) += test_write_rare.o obj-$(CONFIG_KSM) += ksm.o obj-$(CONFIG_PAGE_POISONING) += page_poison.o obj-$(CONFIG_SLAB) += slab.o diff --git a/mm/test_write_rare.c b/mm/test_write_rare.c new file mode 100644 index 000000000000..30574bc34a20 --- /dev/null +++ b/mm/test_write_rare.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * test_write_rare.c + * + * (C) Copyright 2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + */ + +#include +#include +#include +#include +#include + +#ifdef pr_fmt +#undef pr_fmt +#endif + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +extern long __start_wr_after_init; +extern long __end_wr_after_init; + +static __wr_after_init int scalar = '0'; +static __wr_after_init u8 array[PAGE_SIZE * 3] __aligned(PAGE_SIZE); + +/* The section must occupy a non-zero number of whole pages */ +static bool test_alignment(void) +{ + unsigned long pstart = (unsigned long)&__start_wr_after_init; + unsigned long pend = (unsigned long)&__end_wr_after_init; + + if (WARN((pstart & ~PAGE_MASK) || (pend & ~PAGE_MASK) || + (pstart >= pend), "Boundaries test failed.")) + return false; + pr_info("Boundaries test passed."); + return true; +} + +static bool test_pattern(void) +{ + return (memtst(array, '0', PAGE_SIZE / 2) || + memtst(array + PAGE_SIZE / 2, '1', PAGE_SIZE * 3 / 4) || + memtst(array + PAGE_SIZE * 5 / 4, '0', PAGE_SIZE / 2) || + memtst(array + PAGE_SIZE * 7 / 4, '1', PAGE_SIZE * 3 / 4) || + memtst(array + PAGE_SIZE * 5 / 2, '0', PAGE_SIZE / 2)); +} + +static bool test_wr_memset(void) +{ + int new_val = '1'; + + wr_memset(&scalar, new_val, sizeof(scalar)); + if (WARN(memtst(&scalar, new_val, sizeof(scalar)), + "Scalar write rare memset test failed.")) + return false; + + pr_info("Scalar write rare memset test passed."); + + wr_memset(array, '0', PAGE_SIZE * 3); + if (WARN(memtst(array, '0', PAGE_SIZE * 3), + "Array write rare memset test failed.")) + return false; + + wr_memset(array + PAGE_SIZE / 2, '1', PAGE_SIZE * 2); + if (WARN(memtst(array + PAGE_SIZE / 2, '1', PAGE_SIZE * 2), + "Array write rare memset test failed.")) + return false; + + wr_memset(array + PAGE_SIZE * 5 / 4, '0', PAGE_SIZE / 2); + if (WARN(memtst(array + PAGE_SIZE * 5 / 4, '0', PAGE_SIZE / 2), + "Array write rare memset test failed.")) + return false; + + if (WARN(test_pattern(), "Array write rare memset test failed.")) + return false; + + pr_info("Array write rare memset test passed."); + return true; +} + +static u8 array_1[PAGE_SIZE * 2]; +static u8 array_2[PAGE_SIZE * 2]; + +static bool test_wr_memcpy(void) +{ + int new_val = 0x12345678; + + wr_assign(scalar, new_val); + if (WARN(memcmp(&scalar, &new_val, sizeof(scalar)), + "Scalar write rare memcpy test failed.")) + return false; + pr_info("Scalar write rare memcpy test passed."); + + wr_memset(array, '0', PAGE_SIZE * 3); + memset(array_1, '1', PAGE_SIZE * 2); + memset(array_2, '0', PAGE_SIZE * 2); + wr_memcpy(array + PAGE_SIZE / 2, array_1, PAGE_SIZE * 2); + wr_memcpy(array + PAGE_SIZE * 5 / 4, array_2, PAGE_SIZE / 2); + + if (WARN(test_pattern(), "Array write rare memcpy test failed.")) + return false; + + pr_info("Array write rare memcpy test passed."); + return true; +} + +static __wr_after_init int *dst; +static int reference = 0x54; + +static bool test_wr_rcu_assign_pointer(void) +{ + wr_rcu_assign_pointer(dst, &reference); + return dst == &reference; +} + +static int __init test_static_wr_init_module(void) +{ + pr_info("static write_rare test"); + if (WARN(!(test_alignment() && + test_wr_memset() && + test_wr_memcpy() && + test_wr_rcu_assign_pointer()), + "static rare-write test failed")) + return -EFAULT; + pr_info("static write_rare test passed"); + return 0; +} + +module_init(test_static_wr_init_module); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Igor Stoppa "); +MODULE_DESCRIPTION("Test module for static write rare."); From patchwork Fri Dec 21 18:14:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740867 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 19655924 for ; Fri, 21 Dec 2018 18:16:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BABE28426 for ; Fri, 21 Dec 2018 18:16:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F334C28618; Fri, 21 Dec 2018 18:16:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 16AD228426 for ; Fri, 21 Dec 2018 18:16:53 +0000 (UTC) Received: (qmail 3188 invoked by uid 550); 21 Dec 2018 18:15:19 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 3121 invoked from network); 21 Dec 2018 18:15:18 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=9kpmCY6dszhDuHojBIZmAzgP6TFY8woIDvUXpPQug1w=; b=i1aWqsy0VvtYOOA+H+FaFy454gTvRTd9toczqI+B2j3w8dJaT6MdrohN2Nucdkx2uT O7heRehVrBUK1v8nRNP7Qq9H8Hm1aZI05b3pvICKey+/lupkRDm0HDM02tGB+gdbYQ2H QkchLfTMTMrz8CoF5dWFSFNhGcidh1S2e9bKy8KBN+sBGQrfCN/Culgu41PU1KSjx4pC 1PwMUt1P5owoEyJQGQUJa2a1XdLa6n6vqGFNYWOMHkP/0R6R7QYRclERrymq615h3mVP zzjrHTxZh+NZNwUtU17p0X0jbZ0nxaYv7NnWwdHIx+LRUPOg8BzvteriVLu/n62OLVpl xZPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=9kpmCY6dszhDuHojBIZmAzgP6TFY8woIDvUXpPQug1w=; b=MmPnftJ9EFg0A8H2wn37kR1SblKZ1NZmw/JP9muaga5Xpi05vM9OAfleV+qViaLdJZ W86NkikdNYk2Mya0em87sAsu1lK5/W81dabS8qPigwnuEt74ePSo+FMqf9Zj7pL/lOJ5 nBN08z1gPn3rOVsealJtBNzkQHOPWckeKpEDtIEu6kz0qt2YH1W8LfnFLHZnBGJ8YXjN GULJKbqmMt5TG4hcPew62tbmeUbuhaP1vO0MRyFOljwZDpp4dJIYFPIKM4GhPv2hLFcp Drynxlx6NJ1jHHqQD7BaTQ+rGO93nIDgMQPDkpvRVVybUfPL66vwmVIh6kPpEJVJ3Ze5 27VA== X-Gm-Message-State: AA+aEWbPeCOfSc6DsOGnDe9XJEYRdYEu2StsAgXBhQjHhc4dOV39lVwj RsLkZok16IlDLuGrG5dyATc= X-Google-Smtp-Source: AFSGD/VE3JmdMqhdSd8pGYwVsC5amAsiJm8OyCVcYMpbQ5Os9r4eJcEGMW+sUTS5gk2WY62Z99HL/A== X-Received: by 2002:a19:3b9c:: with SMTP id d28mr2119418lfl.30.1545416107450; Fri, 21 Dec 2018 10:15:07 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 11/12] IMA: turn ima_policy_flags into __wr_after_init Date: Fri, 21 Dec 2018 20:14:22 +0200 Message-Id: <20181221181423.20455-12-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP The policy flags could be targeted by an attacker aiming at disabling IMA, so that there would be no trace of a file system modification in the measurement list. Since the flags can be altered at runtime, it is not possible to make them become fully read-only, for example with __ro_after_init. __wr_after_init can still provide some protection, at least against simple memory overwrite attacks Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- security/integrity/ima/ima.h | 3 ++- security/integrity/ima/ima_policy.c | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index cc12f3449a72..297c25f5122e 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "../integrity.h" @@ -50,7 +51,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; #define IMA_TEMPLATE_IMA_FMT "d|n" /* current content of the policy */ -extern int ima_policy_flag; +extern int ima_policy_flag __wr_after_init; /* set during initialization */ extern int ima_hash_algo; diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 7489cb7de6dc..2004de818d92 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -47,7 +47,7 @@ #define INVALID_PCR(a) (((a) < 0) || \ (a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8)) -int ima_policy_flag; +int ima_policy_flag __wr_after_init; static int temp_ima_appraise; static int build_ima_appraise __ro_after_init; @@ -452,12 +452,13 @@ void ima_update_policy_flag(void) list_for_each_entry(entry, ima_rules, list) { if (entry->action & IMA_DO_MASK) - ima_policy_flag |= entry->action; + wr_assign(ima_policy_flag, + ima_policy_flag | entry->action); } ima_appraise |= (build_ima_appraise | temp_ima_appraise); if (!ima_appraise) - ima_policy_flag &= ~IMA_APPRAISE; + wr_assign(ima_policy_flag, ima_policy_flag & ~IMA_APPRAISE); } static int ima_appraise_flag(enum ima_hooks func) @@ -574,7 +575,7 @@ void ima_update_policy(void) list_splice_tail_init_rcu(&ima_temp_rules, policy, synchronize_rcu); if (ima_rules != policy) { - ima_policy_flag = 0; + wr_assign(ima_policy_flag, 0); ima_rules = policy; } ima_update_policy_flag(); From patchwork Fri Dec 21 18:14:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 10740869 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 29A46924 for ; Fri, 21 Dec 2018 18:17:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1D004284AA for ; Fri, 21 Dec 2018 18:17:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 104AF28622; Fri, 21 Dec 2018 18:17:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 2993A284AA for ; Fri, 21 Dec 2018 18:17:05 +0000 (UTC) Received: (qmail 3352 invoked by uid 550); 21 Dec 2018 18:15:21 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 3271 invoked from network); 21 Dec 2018 18:15:20 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=SF4qk+bTzK3es4UM9b0qE6afh8/8sQWLd3sxWcWkQd8=; b=Ii7ELF8/5y1rVaPhHiLhgDtq4P7/rfzqXnM3EeCH5GRSr2Kq2zzNF5t8kZw3ND0+a6 10vlyhvH2ZArYPGzD8PwHtf9EFg96E8dJK8mNhL944qEkX0oPwo3++zWdGQklQ9CWU8B ETzu3Boaxa10N5Nt8r1xtE9gTtRaR9kkLpPgE8BLmp1z/ycZC0NNjjNhkSeV27VB58Vh cylWppIJrf8u0uC15//e4cctuMhk9qlnQyspjtHkl2k33XBKfEPLw9N9gKQ8QuMGKnxR 26HLuc8Ps/OA9fdgIFgv2Zi8d3KV46SAyUsiabS45ayIX64sTa1CQlIsMkc80vD0t48o vIng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=SF4qk+bTzK3es4UM9b0qE6afh8/8sQWLd3sxWcWkQd8=; b=qrjuQOoY+4/ApyW9ewla/Zq/k6Jhf2RnDsYDOMSSphilINTCJ0aC67m+MC1zbd4oPP cF7dF6LgulcTFRlxQe6ruZ3rz9QTuYz0EiaAhFwbdo9koUlN55Js4fwhmrCMeE7/AfaT sYgfWu2cRdfN1xOhx3mI9SykbxIluJPEqO+8kMptKfgG9csJzyN+MqVeOIStwBH9LVma kpWyDTJ3VX49uQkJMdHFmv/g62KrLeGbINVRCSUhObzh46p835Y33J1IOEcsZX+nArW5 vR2ZTK4mjFX3S5Ux1vug9IsihKIoFZd7quB1oe7MkNYrMaDyJN0v3/8QRU/pEaKxCP2y G+Yw== X-Gm-Message-State: AA+aEWaLRx3e4dZT0ZovLX5fxdGKS79UQQRB0wBx5IJDI6g7pIGTfDAl /EFAQ7w6kFwRQ7UX0Q3vP+4= X-Google-Smtp-Source: AFSGD/U5nUYrabzF4bcWijW9jX9KfZDA5WG1g0TgA4b42uvAMM3t6RmJ/Cf3Ft6Rt3AgJtUscpiQGw== X-Received: by 2002:a2e:9cd2:: with SMTP id g18-v6mr2461814ljj.161.1545416109279; Fri, 21 Dec 2018 10:15:09 -0800 (PST) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: Andy Lutomirski , Matthew Wilcox , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann Cc: igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 12/12] x86_64: __clear_user as case of __memset_user Date: Fri, 21 Dec 2018 20:14:23 +0200 Message-Id: <20181221181423.20455-13-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181221181423.20455-1-igor.stoppa@huawei.com> References: <20181221181423.20455-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP To avoid code duplication, re-use __memset_user(), when clearing user-space memory. The overhead should be minimal (2 extra register assignments) and outside of the writing loop. Signed-off-by: Igor Stoppa CC: Andy Lutomirski CC: Nadav Amit CC: Matthew Wilcox CC: Peter Zijlstra CC: Kees Cook CC: Dave Hansen CC: Mimi Zohar CC: Thiago Jung Bauermann CC: Ahmed Soliman CC: linux-integrity@vger.kernel.org CC: kernel-hardening@lists.openwall.com CC: linux-mm@kvack.org CC: linux-kernel@vger.kernel.org --- arch/x86/lib/usercopy_64.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 84f8f8a20b30..ab6aabb62055 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -69,34 +69,7 @@ EXPORT_SYMBOL(memset_user); unsigned long __clear_user(void __user *addr, unsigned long size) { - long __d0; - might_fault(); - /* no memory constraint because it doesn't change any memory gcc knows - about */ - stac(); - asm volatile( - " testq %[size8],%[size8]\n" - " jz 4f\n" - "0: movq $0,(%[dst])\n" - " addq $8,%[dst]\n" - " decl %%ecx ; jnz 0b\n" - "4: movq %[size1],%%rcx\n" - " testl %%ecx,%%ecx\n" - " jz 2f\n" - "1: movb $0,(%[dst])\n" - " incq %[dst]\n" - " decl %%ecx ; jnz 1b\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3: lea 0(%[size1],%[size8],8),%[size8]\n" - " jmp 2b\n" - ".previous\n" - _ASM_EXTABLE_UA(0b, 3b) - _ASM_EXTABLE_UA(1b, 2b) - : [size8] "=&c"(size), [dst] "=&D" (__d0) - : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr)); - clac(); - return size; + return __memset_user(addr, 0, size); } EXPORT_SYMBOL(__clear_user);