From patchwork Mon Oct 4 22:42:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Matthew Wilcox (Oracle)" X-Patchwork-Id: 12535079 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F13BEC433EF for ; Mon, 4 Oct 2021 22:44:37 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 033FE61407 for ; Mon, 4 Oct 2021 22:44:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 033FE61407 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id 5D3DA940072; Mon, 4 Oct 2021 18:44:36 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 581FF94000B; Mon, 4 Oct 2021 18:44:36 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 47168940072; Mon, 4 Oct 2021 18:44:36 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0224.hostedemail.com [216.40.44.224]) by kanga.kvack.org (Postfix) with ESMTP id 3966994000B for ; Mon, 4 Oct 2021 18:44:36 -0400 (EDT) Received: from smtpin12.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id D2197181C9900 for ; Mon, 4 Oct 2021 22:44:35 +0000 (UTC) X-FDA: 78660235710.12.BA287C7 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf22.hostedemail.com (Postfix) with ESMTP id 9152B1F7E for ; Mon, 4 Oct 2021 22:44:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=Pb/cVPOsNt/BSSvk3sInOMQVJXLvuiJVENnhajZ7z2w=; b=Fm4eL4jNqS0v+mK4JVacdb3o36 ye8W9Sga+YSkUWpmj78TDakLmoENRl4KE4ECNAjGT3kWSShg5YWS9x5/SUTCyo6nb9zkrsR4HnUbu FaIAjnxzSkIYrrn2QEGmTy9gLADXtiGezJccqbj51CS5PMFs3F2U8PCpWFSvRJpHwklpFVKMol9hz MvCMH3mASVNqgZeyolJdqRda8hBFKsEb9rXZXc2aB3Y7P0L5y6FFNBcCDX30MD+uJ9yXP4F3+Cvlt NaOypvIE31lMUS6/LGIJf8KxXbHfH7KhbfEjCjT7mUO5qmMht68mq3IHolpJe6D2koDumH5l3L/RO 7yS8PV9Q==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1mXWfY-00HMUk-U1; Mon, 04 Oct 2021 22:43:09 +0000 From: "Matthew Wilcox (Oracle)" To: Kees Cook Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, Thomas Gleixner Subject: [PATCH 1/3] mm/usercopy: Check kmap addresses properly Date: Mon, 4 Oct 2021 23:42:21 +0100 Message-Id: <20211004224224.4137992-2-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211004224224.4137992-1-willy@infradead.org> References: <20211004224224.4137992-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Server: rspam01 X-Rspamd-Queue-Id: 9152B1F7E X-Stat-Signature: dti9puxu5754n4fqh9ociajrz779nso1 Authentication-Results: imf22.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=Fm4eL4jN; dmarc=none; spf=none (imf22.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org X-HE-Tag: 1633387475-776343 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: If you are copying to an address in the kmap region, you may not copy across a page boundary, no matter what the size of the underlying allocation. You can't kmap() a slab page because slab pages always come from low memory. Signed-off-by: Matthew Wilcox (Oracle) Acked-by: Kees Cook --- arch/x86/include/asm/highmem.h | 1 + include/linux/highmem-internal.h | 10 ++++++++++ mm/usercopy.c | 15 +++++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h index 032e020853aa..731ee7cc40a5 100644 --- a/arch/x86/include/asm/highmem.h +++ b/arch/x86/include/asm/highmem.h @@ -26,6 +26,7 @@ #include #include #include +#include /* declarations for highmem.c */ extern unsigned long highstart_pfn, highend_pfn; diff --git a/include/linux/highmem-internal.h b/include/linux/highmem-internal.h index 4aa1031d3e4c..97d6dc836749 100644 --- a/include/linux/highmem-internal.h +++ b/include/linux/highmem-internal.h @@ -143,6 +143,11 @@ static inline void totalhigh_pages_add(long count) atomic_long_add(count, &_totalhigh_pages); } +static inline bool is_kmap_addr(const void *x) +{ + unsigned long addr = (unsigned long)x; + return addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP); +} #else /* CONFIG_HIGHMEM */ static inline struct page *kmap_to_page(void *addr) @@ -223,6 +228,11 @@ static inline void __kunmap_atomic(void *addr) static inline unsigned int nr_free_highpages(void) { return 0; } static inline unsigned long totalhigh_pages(void) { return 0UL; } +static inline bool is_kmap_addr(const void *x) +{ + return false; +} + #endif /* CONFIG_HIGHMEM */ /* diff --git a/mm/usercopy.c b/mm/usercopy.c index b3de3c4eefba..ac95b22fbbce 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -228,12 +228,15 @@ static inline void check_heap_object(const void *ptr, unsigned long n, if (!virt_addr_valid(ptr)) return; - /* - * When CONFIG_HIGHMEM=y, kmap_to_page() will give either the - * highmem page or fallback to virt_to_page(). The following - * is effectively a highmem-aware virt_to_head_page(). - */ - page = compound_head(kmap_to_page((void *)ptr)); + if (is_kmap_addr(ptr)) { + unsigned long page_end = (unsigned long)ptr | (PAGE_SIZE - 1); + + if ((unsigned long)ptr + n - 1 > page_end) + usercopy_abort("kmap", NULL, to_user, 0, n); + return; + } + + page = virt_to_head_page(ptr); if (PageSlab(page)) { /* Check slab allocator for flags and size. */ From patchwork Mon Oct 4 22:42:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Matthew Wilcox (Oracle)" X-Patchwork-Id: 12535081 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AD20C433EF for ; Mon, 4 Oct 2021 22:45:10 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 37C0861407 for ; Mon, 4 Oct 2021 22:45:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 37C0861407 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id 8DF95940073; Mon, 4 Oct 2021 18:45:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 88F1394000B; Mon, 4 Oct 2021 18:45:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 77E63940073; Mon, 4 Oct 2021 18:45:09 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0198.hostedemail.com [216.40.44.198]) by kanga.kvack.org (Postfix) with ESMTP id 6672294000B for ; Mon, 4 Oct 2021 18:45:09 -0400 (EDT) Received: from smtpin05.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id 209603207A for ; Mon, 4 Oct 2021 22:45:09 +0000 (UTC) X-FDA: 78660237138.05.ABB16D5 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf26.hostedemail.com (Postfix) with ESMTP id CF40620061CB for ; Mon, 4 Oct 2021 22:45:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=xo8dM9lluT6Si5UeuSZCoPD7FDaxI+l3q2VgSdl1KPc=; b=bIhgC4qYxfp5W2LAjbC/oDUw5C WU7MyODAY7I7LFvJYwrAAMcC3U62HhQT2X78JxgVihaH8sWq3JIUyHB08/m0y58R0PCLVW5ZsOAv1 NlXVgrXRdbZle4l4sSiqRzOHblMjbUZoUn3+yyLzQ0qmSu1o/voThOgTsYArq3adccQIBInqZ1Bca 0rop/IbLNu8mhTrs1rp6s0dB0bRyk0gD8XHCjDx7g/TlBBX/dQHcJKYPJOeuT48a929cciQkjuz53 tkqEPaCGiVGp3NxR8PwLli0FDyeR9+u/Kbr1g2cyK0SoWge4aukN0sRxeWZOgbJqpBcEZTux3UY1t NlHPYLBg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1mXWge-00HMW5-QX; Mon, 04 Oct 2021 22:44:17 +0000 From: "Matthew Wilcox (Oracle)" To: Kees Cook Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, Thomas Gleixner Subject: [PATCH 2/3] mm/usercopy: Detect vmalloc overruns Date: Mon, 4 Oct 2021 23:42:22 +0100 Message-Id: <20211004224224.4137992-3-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211004224224.4137992-1-willy@infradead.org> References: <20211004224224.4137992-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: CF40620061CB X-Stat-Signature: hj46utxwihaxdmbk9htqu6bsjp8oqddq Authentication-Results: imf26.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=bIhgC4qY; dmarc=none; spf=none (imf26.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org X-HE-Tag: 1633387508-338025 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: If you have a vmalloc() allocation, or an address from calling vmap(), you cannot overrun the vm_area which describes it, regardless of the size of the underlying allocation. This probably doesn't do much for security because vmalloc comes with guard pages these days, but it prevents usercopy aborts when copying to a vmap() of smaller pages. Signed-off-by: Matthew Wilcox (Oracle) Acked-by: Kees Cook --- mm/usercopy.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm/usercopy.c b/mm/usercopy.c index ac95b22fbbce..7bfc4f9ed1e4 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -236,6 +237,14 @@ static inline void check_heap_object(const void *ptr, unsigned long n, return; } + if (is_vmalloc_addr(ptr)) { + struct vm_struct *vm = find_vm_area(ptr); + + if (ptr + n > vm->addr + vm->size) + usercopy_abort("vmalloc", NULL, to_user, 0, n); + return; + } + page = virt_to_head_page(ptr); if (PageSlab(page)) { From patchwork Mon Oct 4 22:42:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Matthew Wilcox (Oracle)" X-Patchwork-Id: 12535083 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C425DC433EF for ; Mon, 4 Oct 2021 22:46:09 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 70BB461506 for ; Mon, 4 Oct 2021 22:46:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 70BB461506 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id 11558940074; Mon, 4 Oct 2021 18:46:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 09F5C94000B; Mon, 4 Oct 2021 18:46:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E5B5F940074; Mon, 4 Oct 2021 18:46:08 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id D210694000B for ; Mon, 4 Oct 2021 18:46:08 -0400 (EDT) Received: from smtpin25.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id 99E2B2CBBA for ; Mon, 4 Oct 2021 22:46:08 +0000 (UTC) X-FDA: 78660239616.25.BFC8B4A Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf22.hostedemail.com (Postfix) with ESMTP id 5CA9E31C3 for ; Mon, 4 Oct 2021 22:46:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=CxZ+S2dey61N1rPAOujjNfz8KYhMeyKgJQ6ggvHKlMo=; b=fomvCjU55/qmfkO73k1xtXLYqh LcyVarpBpx5mtV4h/stihEmLzuIJ6ZK1KNLTugJL7Wc3SbWyV4gFUGy3zPR2ayLOabt/GfbZbpR1C bY24mqTUfMMGAWN4w76qk1I80CTy29PlzoFXjknJTbRhQDMPu8gp3cnLfGqPda3N6RLkjqGfYgRKY kRBOMaTlS1knv/+MSs1z7rO4B+//7zND0NkkSMW51ogQwxCd+QOI8UtmIFXCb7RA7gVf/9n+nfibK O7GM7cXVryU8Psw+Stn8oameeEIrIUnRuv4a9WXtccK+FdIs4di9nXROtn/XadyQF7teT9l3JKk2k ABtkoWMg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1mXWhQ-00HMXA-Ao; Mon, 04 Oct 2021 22:44:53 +0000 From: "Matthew Wilcox (Oracle)" To: Kees Cook Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, Thomas Gleixner Subject: [PATCH 3/3] mm/usercopy: Detect compound page overruns Date: Mon, 4 Oct 2021 23:42:23 +0100 Message-Id: <20211004224224.4137992-4-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211004224224.4137992-1-willy@infradead.org> References: <20211004224224.4137992-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: 5CA9E31C3 X-Stat-Signature: b3tr9xqna3wn44ng9ymkctf8b35yufeg Authentication-Results: imf22.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=fomvCjU5; dmarc=none; spf=none (imf22.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org X-HE-Tag: 1633387568-734676 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Move the compound page overrun detection out of CONFIG_HARDENED_USERCOPY_PAGESPAN so it's enabled for more people. Signed-off-by: Matthew Wilcox (Oracle) Acked-by: Kees Cook --- mm/usercopy.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/usercopy.c b/mm/usercopy.c index 7bfc4f9ed1e4..e395462961d5 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -194,11 +194,6 @@ static inline void check_page_span(const void *ptr, unsigned long n, ((unsigned long)end & (unsigned long)PAGE_MASK))) return; - /* Allow if fully inside the same compound (__GFP_COMP) page. */ - endpage = virt_to_head_page(end); - if (likely(endpage == page)) - return; - /* * Reject if range is entirely either Reserved (i.e. special or * device memory), or CMA. Otherwise, reject since the object spans @@ -250,6 +245,10 @@ static inline void check_heap_object(const void *ptr, unsigned long n, if (PageSlab(page)) { /* Check slab allocator for flags and size. */ __check_heap_object(ptr, n, page, to_user); + } else if (PageHead(page)) { + /* A compound allocation */ + if (ptr + n > page_address(page) + page_size(page)) + usercopy_abort("page alloc", NULL, to_user, 0, n); } else { /* Verify object does not incorrectly span multiple pages. */ check_page_span(ptr, n, page, to_user);