From patchwork Mon Jan 10 23:15:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 12709262 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 40A07C4332F for ; Mon, 10 Jan 2022 23:15:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5833F6B0074; Mon, 10 Jan 2022 18:15:39 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 5315B6B0075; Mon, 10 Jan 2022 18:15:39 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 3D1CB6B0078; Mon, 10 Jan 2022 18:15:39 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0119.hostedemail.com [216.40.44.119]) by kanga.kvack.org (Postfix) with ESMTP id 2BE0F6B0074 for ; Mon, 10 Jan 2022 18:15:39 -0500 (EST) Received: from smtpin17.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id CC71C181CAEF8 for ; Mon, 10 Jan 2022 23:15:38 +0000 (UTC) X-FDA: 79015936356.17.AE6EB38 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf07.hostedemail.com (Postfix) with ESMTP id DF42C40009 for ; Mon, 10 Jan 2022 23:15:37 +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=nYSnqKs9eUHoLhXGMAa3D+i7diZP4kPH2WYq8LEVbfQ=; b=LNkuwdwOG/DhLYe+dCZA7hAGXP lLVMd7rapIm35q3VHLji7eGhYqSIt/rl++mn5ejylF+IeoBJO14ZtB0B4sw7HswMbI3nkhQC6Xg/H cL8NSVjmXU+5/hgwLkmAi0gYZvyyheywxnijj0Z6Rk4I9iTbMtFVgq6TnrsQy4vJ+ZS61+Ov2Uhy/ L/FvXOEZSnjPjv+3n6oMRV5Bf6OG5iwe0LSLuHfeWfXLdIs0E3GsvsXM3+AUgnlgHkMNeWzkA0f7j Eg7nLBGxUPCxMdpdlh/BNgAE0eiN99LApbpQuTDOEH7IqsRGTSqOJuL900phQx4ocQ2XsKEYDVKDR r9whMWlQ==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1n73sy-002nGH-Fy; Mon, 10 Jan 2022 23:15:32 +0000 From: "Matthew Wilcox (Oracle)" To: Kees Cook Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, linux-hardening@vger.kernel.org Subject: [PATCH 2/4] mm/usercopy: Detect vmalloc overruns Date: Mon, 10 Jan 2022 23:15:28 +0000 Message-Id: <20220110231530.665970-3-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220110231530.665970-1-willy@infradead.org> References: <20220110231530.665970-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: DF42C40009 X-Stat-Signature: nbsszjqweejeqoz7iyqhdtut9osc6f6f Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=LNkuwdwO; spf=none (imf07.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: 1641856537-870882 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 2d13bc3bd83b..dcf71b7e3098 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -238,6 +239,21 @@ static inline void check_heap_object(const void *ptr, unsigned long n, return; } + if (is_vmalloc_addr(ptr)) { + struct vm_struct *area = find_vm_area(ptr); + unsigned long offset; + + if (!area) { + usercopy_abort("vmalloc", "no area", to_user, 0, n); + return; + } + + offset = ptr - area->addr; + if (offset + n > get_vm_area_size(area)) + usercopy_abort("vmalloc", NULL, to_user, offset, n); + return; + } + folio = virt_to_folio(ptr); if (folio_test_slab(folio)) {