From patchwork Mon Dec 13 14:27:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 12674033 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63D01C433EF for ; Mon, 13 Dec 2021 14:27:46 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6D1466B0073; Mon, 13 Dec 2021 09:27:19 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 62AD86B0078; Mon, 13 Dec 2021 09:27:19 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 33E1C6B0073; Mon, 13 Dec 2021 09:27:19 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0001.hostedemail.com [216.40.44.1]) by kanga.kvack.org (Postfix) with ESMTP id 1C7526B0073 for ; Mon, 13 Dec 2021 09:27:19 -0500 (EST) Received: from smtpin09.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id BAF1988487 for ; Mon, 13 Dec 2021 14:27:08 +0000 (UTC) X-FDA: 78912998136.09.4B3EA53 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf12.hostedemail.com (Postfix) with ESMTP id DA69440007 for ; Mon, 13 Dec 2021 14:27:03 +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=FaGT0W88prg5rCbGEk97JZKHxNwNL3WzIICgEAogG4E=; b=mtLnrhgjys1pqoGO33djIsde2C 8HmUctiwvH5oR5DW9wWo0s0HdWUgQ1mJbtegHveMzx0s3U1pZQP5gNSDCVFu261pmWunSPKgOFcA1 ysU1GynwW/iXshue2VuFpeTg+2lftBEbO4V2gZvT3LmeSEIoi3H7rlXnWQ2FXa0BiGkQq2aksrbTO 0e5WZmown/Qp2+9cgPieU6JasAZ/UOB/CipIcx6WEFz2htWixAfE9nQKUriINXvCIGcSMkk4MdM94 IC3k8tBonM7R+pNu8CsILjWvb2nFyBQh6PPRJ9DTzYqvk8pxWqUGHrXUoS1PZGe/wbwtlyUUQNiWE N9wujDPw==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1mwmID-00Crlv-8z; Mon, 13 Dec 2021 14:27:05 +0000 From: "Matthew Wilcox (Oracle)" To: Kees Cook Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, Thomas Gleixner , linux-hardening@vger.kernel.org Subject: [PATCH v3 2/3] mm/usercopy: Detect vmalloc overruns Date: Mon, 13 Dec 2021 14:27:02 +0000 Message-Id: <20211213142703.3066590-3-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211213142703.3066590-1-willy@infradead.org> References: <20211213142703.3066590-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: DA69440007 X-Stat-Signature: mqihwsr6efdhywmob1bdio1xstegsjrh Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=mtLnrhgj; spf=none (imf12.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org; dmarc=none X-HE-Tag: 1639405623-732463 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 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mm/usercopy.c b/mm/usercopy.c index 8c039302465f..63476e1506e0 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -237,6 +238,21 @@ 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); + unsigned long offset; + + if (!vm) { + usercopy_abort("vmalloc", "no area", to_user, 0, n); + return; + } + + offset = ptr - vm->addr; + if (offset + n > vm->size) + usercopy_abort("vmalloc", NULL, to_user, offset, n); + return; + } + page = virt_to_head_page(ptr); if (PageSlab(page)) {