Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp7491582ybi; Wed, 5 Jun 2019 19:13:20 -0700 (PDT) X-Google-Smtp-Source: APXvYqzhC5T3Yu6zvMOL2HGnnZvNcx4RquDfQNRwJ3vXBkiJDVMmdqVLiIvQlPU7WITMapRbcaci X-Received: by 2002:a63:a055:: with SMTP id u21mr894232pgn.5.1559787200246; Wed, 05 Jun 2019 19:13:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559787200; cv=none; d=google.com; s=arc-20160816; b=t/8eOAelFvqqabzCG2dKUTRQcyaAvOceVsZG4S+lkiA0GY5rWW/HvjFDiyVfHW1j9b fleK4HHMpWLBkWSmH7Q7/uw8LMt9rLMjfwAQVz37eYJPzCGEz8j2lI/Z7Ux1AQ6HrNS0 kDcTVjI10TRExmPUyCXP0JjZec4uTO+1xGXAupZppcxC6W0fGRyEr+xPTShN5rPP0Zrc zCDxMNmkBocCDzhv6ojkbJq9S4EbLHVweJl6heNinS5ZHEYQG7IlrGao5lITbIveobju YIM0j6gS4TavP+5qgbYK32ByUKIYXHh02S8wG8nlk4BPunhqN6GYWDuXOLMu12u9EnWx QAKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=OPUZKRIwPMgwKKcWYp/JSR3JeNppRmseZ8rDy1gQk14=; b=EDYcW/r5LS6nAtA4Lzt5FGzOBaKJU7wU4WQGR1jx2vwSKzXCPd7XGRIFK3BgjgOaB/ relKTf1Wgf0KBsDA51aB01kro5l47VTIn7fNtP2B9INKKwSpCo6F7975xbaBw3fO9VYZ 5DPP9orZyDzmLvRIKftjil8p4rE8ekivvczNlTEcB7dPae+qID6bCElAMv0HvOpItmIG 8Kma3AmOtB7lao0mXqy6bnhTnumfjduUQm04hz0xbUyL0Y1wn73k4irhpa/NtuClmBh3 fy+dp6T/tjH56TBjYvc5iX2Qfm0pJ7qFfsEe6U2/i3WWZhSFyJyU+/s/CBMP69f+4RV9 kctQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u1si295073pls.194.2019.06.05.19.13.03; Wed, 05 Jun 2019 19:13:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726761AbfFFCLw (ORCPT + 99 others); Wed, 5 Jun 2019 22:11:52 -0400 Received: from mga17.intel.com ([192.55.52.151]:61631 "EHLO mga17.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726589AbfFFCLu (ORCPT ); Wed, 5 Jun 2019 22:11:50 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 19:11:49 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga004.jf.intel.com with ESMTP; 05 Jun 2019 19:11:49 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: Andy Lutomirski , Cedric Xing , Stephen Smalley , James Morris , "Serge E . Hallyn" , LSM List , Paul Moore , Eric Paris , selinux@vger.kernel.org, Jethro Beekman , Dave Hansen , Thomas Gleixner , Linus Torvalds , LKML , X86 ML , linux-sgx@vger.kernel.org, Andrew Morton , nhorman@redhat.com, npmccallum@redhat.com, Serge Ayoun , Shay Katz-zamir , Haitao Huang , Andy Shevchenko , Kai Svahn , Borislav Petkov , Josh Triplett , Kai Huang , David Rientjes , William Roberts , Philip Tricca Subject: [RFC PATCH v2 1/5] mm: Introduce vm_ops->may_mprotect() Date: Wed, 5 Jun 2019 19:11:41 -0700 Message-Id: <20190606021145.12604-2-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190606021145.12604-1-sean.j.christopherson@intel.com> References: <20190606021145.12604-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org SGX will use the may_mprotect() hook to prevent userspace from circumventing various security checks, e.g. Linux Security Modules. Naming it may_mprotect() instead of simply mprotect() is intended to reflect the hook's purpose as a way to gate mprotect() as opposed to a wholesale replacement. Enclaves are built by copying data from normal memory into the Enclave Page Cache (EPC). Due to the nature of SGX, the EPC is represented by a single file that must be MAP_SHARED, i.e. mprotect() only ever sees a MAP_SHARED vm_file that references single file path. Furthermore, all enclaves will need read, write and execute pages in the EPC. As a result, LSM policies cannot be meaningfully applied, e.g. an LSM can deny access to the EPC as a whole, but can't deny PROT_EXEC on page that originated in a non-EXECUTE file (which is long gone by the time mprotect() is called). By hooking mprotect(), SGX can make explicit LSM upcalls while an enclave is being built, i.e. when the kernel has a handle to origin of each enclave page, and enforce the result of the LSM policy whenever userspace maps the enclave page in the future. Alternatively, SGX could play games with MAY_{READ,WRITE,EXEC}, but that approach is quite ugly, e.g. would require userspace to call an SGX ioctl() prior to using mprotect() to extend a page's protections. Signed-off-by: Sean Christopherson --- include/linux/mm.h | 2 ++ mm/mprotect.c | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 0e8834ac32b7..a697996040ac 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -458,6 +458,8 @@ 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); + int (*may_mprotect)(struct vm_area_struct * area, unsigned long start, + unsigned long end, unsigned long prot); 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 bf38dfbbb4b4..18732543b295 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -547,13 +547,20 @@ static int do_mprotect_pkey(unsigned long start, size_t len, goto out; } - error = security_file_mprotect(vma, reqprot, prot); - if (error) - goto out; - tmp = vma->vm_end; if (tmp > end) tmp = end; + + if (vma->vm_ops && vma->vm_ops->may_mprotect) { + error = vma->vm_ops->may_mprotect(vma, nstart, tmp, prot); + if (error) + goto out; + } + + error = security_file_mprotect(vma, reqprot, prot); + if (error) + goto out; + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); if (error) goto out; -- 2.21.0