From patchwork Thu Dec 16 21:53:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 12682805 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 7A7A2C433EF for ; Thu, 16 Dec 2021 21:55:11 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 92E5C6B0071; Thu, 16 Dec 2021 16:54:11 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 8DBBC6B0075; Thu, 16 Dec 2021 16:54:11 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7A36B6B0078; Thu, 16 Dec 2021 16:54:11 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0143.hostedemail.com [216.40.44.143]) by kanga.kvack.org (Postfix) with ESMTP id 67E156B0071 for ; Thu, 16 Dec 2021 16:54:11 -0500 (EST) Received: from smtpin07.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id 24DD78906A for ; Thu, 16 Dec 2021 21:54:01 +0000 (UTC) X-FDA: 78925010682.07.CF9FF55 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf20.hostedemail.com (Postfix) with ESMTP id 42FC61C001D for ; Thu, 16 Dec 2021 21:53:58 +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=dlV3pNPMcMviclf5RhZNDIDmGBRDvRI+kfEWSJSDVkk=; b=a5rViquGApQES/ro+eHyDlumcs 160F+ADE5SQRRimF9Cgdlegh0C+3Dw8YOhFmXZPEgEloXTtGY/I8CRteFwJBO5+8FKLOIrkoR7XRW 3NxBzMzmwyo2Q9SGMUJqPnRmA4DcsN+Muf4x0YomNyH5CiA55zMjdrTcygM556Z2xFtiiIDsjdW/y 1Gqz/1+CvNcvz/L34z/e14/HITS7g1xl+5l+rSjyfq+FjRLBtdqANW964qpRWcb6PUoCQ/evYrl2L cLH6JYCbxRnCzpabI3ahplPPWEM0pE6hfWSnK8cBFYLDvRmHPlb8WVRm3mjd8860IUe+3F6OTcoEb HFUton9w==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1mxyhE-00FzY8-Op; Thu, 16 Dec 2021 21:53:52 +0000 From: "Matthew Wilcox (Oracle)" To: Kees Cook Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, linux-hardening@vger.kernel.org, William Kucharski Subject: [PATCH v4 2/4] mm/usercopy: Detect vmalloc overruns Date: Thu, 16 Dec 2021 21:53:49 +0000 Message-Id: <20211216215351.3811471-3-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211216215351.3811471-1-willy@infradead.org> References: <20211216215351.3811471-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 42FC61C001D X-Stat-Signature: uinfkdismio39gp5oqjtx7okbhxj69zc Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=a5rViquG; spf=none (imf20.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: 1639691638-43111 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 Reviewed-by: William Kucharski --- 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)) {