From patchwork Thu Nov 12 22:01:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 11901783 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D264B697 for ; Thu, 12 Nov 2020 22:02:55 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 713722224A for ; Thu, 12 Nov 2020 22:02:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="XwQqrGiZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 713722224A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 6AAEC6B005D; Thu, 12 Nov 2020 17:02:54 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 682116B0068; Thu, 12 Nov 2020 17:02:54 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5BF2A6B006E; Thu, 12 Nov 2020 17:02:54 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0232.hostedemail.com [216.40.44.232]) by kanga.kvack.org (Postfix) with ESMTP id 308426B005D for ; Thu, 12 Nov 2020 17:02:54 -0500 (EST) Received: from smtpin04.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id C66643625 for ; Thu, 12 Nov 2020 22:02:53 +0000 (UTC) X-FDA: 77477141826.04.lunch90_050000627309 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin04.hostedemail.com (Postfix) with ESMTP id AA160800ABCD for ; Thu, 12 Nov 2020 22:02:53 +0000 (UTC) X-Spam-Summary: 1,0,0,0c232cd320996589,d41d8cd98f00b204,jarkko@kernel.org,,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1311:1313:1314:1345:1359:1431:1437:1515:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:2393:2553:2559:2562:2693:2903:3138:3139:3140:3141:3142:3355:3865:3866:3867:3868:3870:3871:3872:3874:4250:4321:4470:4605:5007:6119:6261:6653:6742:6743:7576:7903:10004:10400:11026:11232:11473:11658:11914:12043:12114:12296:12297:12438:12517:12519:12555:12679:12895:12986:13053:13149:13161:13229:13230:13846:13894:14096:14097:14181:14394:14659:14721:21080:21433:21451:21627:21990:30054:30064:30090:30091,0,RBL:198.145.29.99:@kernel.org:.lbl8.mailshell.net-62.2.0.100 64.100.201.201;04yr8qfaaoqahahq93thpnprjthc3opanyg56e5th6chow8bxyiqww9np7xnsqx.bcwfet4do1twts8pdafyziyqg4nwbjsxy7da8wxiokk5aax8swq3drwigxb85ys.r-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0 ,LFtime: X-HE-Tag: lunch90_050000627309 X-Filterd-Recvd-Size: 5886 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by imf16.hostedemail.com (Postfix) with ESMTP for ; Thu, 12 Nov 2020 22:02:52 +0000 (UTC) Received: from suppilovahvero.lan (83-245-197-237.elisa-laajakaista.fi [83.245.197.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D1B8F22201; Thu, 12 Nov 2020 22:02:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1605218572; bh=ZmhXE36jtL3HtMS5ufKNwCYsk50uyD05pQfvQHhjPtA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XwQqrGiZ8FvcBpWtUgQK4Puj96Spdfn6UulQro7zxzl4yPt52jLe17aL7qRkiArta C2mc2wnK2xOIa3PEz6al5Tzo0BreT+1NKF5x1IAQc+78BHYN4nVW7Z1OroQB9G6tDX SMFU+lYa+wPnnvzOOyYpwCwzD6XPfMeaBF65TdsY= From: Jarkko Sakkinen To: x86@kernel.org, linux-sgx@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Sean Christopherson , linux-mm@kvack.org, Andrew Morton , Matthew Wilcox , Mel Gorman , Jethro Beekman , Dave Hansen , Jarkko Sakkinen , andriy.shevchenko@linux.intel.com, asapek@google.com, bp@alien8.de, cedric.xing@intel.com, chenalexchen@google.com, conradparker@google.com, cyhanish@google.com, haitao.huang@intel.com, kai.huang@intel.com, kai.svahn@intel.com, kmoy@google.com, ludloff@google.com, luto@kernel.org, nhorman@redhat.com, npmccallum@redhat.com, puiterwijk@redhat.com, rientjes@google.com, tglx@linutronix.de, yaozhangx@google.com, mikko.ylinen@intel.com Subject: [PATCH v41 10/24] mm: Add 'mprotect' hook to struct vm_operations_struct Date: Fri, 13 Nov 2020 00:01:21 +0200 Message-Id: <20201112220135.165028-11-jarkko@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201112220135.165028-1-jarkko@kernel.org> References: <20201112220135.165028-1-jarkko@kernel.org> MIME-Version: 1.0 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: From: Sean Christopherson Background ========== 1. SGX enclave pages are populated with data by copying from normal memory via ioctl() (SGX_IOC_ENCLAVE_ADD_PAGES), which will be added later in this series. 2. It is desirable to be able to restrict those normal memory data sources. For instance, to ensure that the source data is executable before copying data to an executable enclave page. 3. Enclave page permissions are dynamic (just like normal permissions) and can be adjusted at runtime with mprotect(). This creates a problem because the original data source may have long since vanished at the time when enclave page permissions are established (mmap() or mprotect()). The solution (elsewhere in this series) is to force enclaves creators to declare their paging permission *intent* up front to the ioctl(). This intent can be immediately compared to the source data’s mapping and rejected if necessary. The “intent” is also stashed off for later comparison with enclave PTEs. This ensures that any future mmap()/mprotect() operations performed by the enclave creator or done on behalf of the enclave can be compared with the earlier declared permissions. Problem ======= There is an existing mmap() hook which allows SGX to perform this permission comparison at mmap() time. However, there is no corresponding ->mprotect() hook. Solution ======== Add a vm_ops->mprotect() hook so that mprotect() operations which are inconsistent with any page's stashed intent can be rejected by the driver. Cc: linux-mm@kvack.org Cc: Andrew Morton Cc: Matthew Wilcox Cc: Mel Gorman Acked-by: Jethro Beekman # v40 Acked-by: Dave Hansen # v40 # Signed-off-by: Sean Christopherson Co-developed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Acked-by: Mel Gorman Tested-by: Dr. Greg Signed-off-by: Dr. Greg --- Changes from v40: * Move mprotect_fixup() outside of the callback. This keeps mm internals outside of the callback. include/linux/mm.h | 7 +++++++ mm/mprotect.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index db6ae4d3fb4e..1813fa86b981 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -559,6 +559,13 @@ struct vm_operations_struct { void (*close)(struct vm_area_struct * area); int (*split)(struct vm_area_struct * area, unsigned long addr); int (*mremap)(struct vm_area_struct * area); + /* + * Called by mprotect() to make driver-specific permission + * checks before mprotect() is finalised. The VMA must not + * be modified. Returns 0 if eprotect() can proceed. + */ + int (*mprotect)(struct vm_area_struct *vma, unsigned long start, + unsigned long end, unsigned long newflags); vm_fault_t (*fault)(struct vm_fault *vmf); vm_fault_t (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size); diff --git a/mm/mprotect.c b/mm/mprotect.c index 56c02beb6041..ab709023e9aa 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -616,9 +616,16 @@ static int do_mprotect_pkey(unsigned long start, size_t len, tmp = vma->vm_end; if (tmp > end) tmp = end; + + if (vma->vm_ops && vma->vm_ops->mprotect) + error = vma->vm_ops->mprotect(vma, nstart, tmp, newflags); + if (error) + goto out; + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); if (error) goto out; + nstart = tmp; if (nstart < prev->vm_end)