From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE, SPF_PASS,T_DKIMWL_WL_HIGH autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F128FC28CC3 for ; Tue, 4 Jun 2019 14:51:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CB5DC2166E for ; Tue, 4 Jun 2019 14:51:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559659912; bh=5ctEf83W1rzW6eB+79+i8bY5zg2vYEZv2TuztgDU1RY=; h=References:In-Reply-To:From:Date:Subject:To:Cc:List-ID:From; b=DpyhPpQyX7OV9uWCEuMNq1Q527+aWPlC6UiPeE+qZM3aPZcu+wFUKhC709/+QR3Fq 0BFTDBBX5Glb0lNEhkeqMLDvvnZfUSnebv26i8diNcDLBLxJ117fAYAV6cRKFwSqs4 d/hfO8f/BxvY97hOG+/h7eD9+rQj9tT8gGlvN4vU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727787AbfFDOvw (ORCPT ); Tue, 4 Jun 2019 10:51:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:33698 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727623AbfFDOvu (ORCPT ); Tue, 4 Jun 2019 10:51:50 -0400 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) (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 6BDCB223CB for ; Tue, 4 Jun 2019 14:51:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559659909; bh=5ctEf83W1rzW6eB+79+i8bY5zg2vYEZv2TuztgDU1RY=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Z5muKAvqiH60dr+oNPEC5AgAynLm9WObA1y/7r3P5vBrYOMRVlNWOziGBm96tx8jy 33EdItZ/kx1zx2ArVzadldXmio1CnXaZVB+cf5KkQBUyoV+JBNsoC/Zc17ggxYccHH rsc7CH3kNqzgv6bujbnoiS28SXtUqo/CVBeSFWsI= Received: by mail-wr1-f52.google.com with SMTP id f9so1433860wre.12 for ; Tue, 04 Jun 2019 07:51:49 -0700 (PDT) X-Gm-Message-State: APjAAAVABlXjAr0L8X0hmecbRm9qcSEUA9qIaTgTiaPxZCyeEBNavWCB Spe4Xy8xQWnmUfV/WlhHmeCFGWfADpWRF/hwHz6MbQ== X-Google-Smtp-Source: APXvYqwSuFe0LRPOuT6rqk2lttgw4kckoPd0dgTaQOVZmyVeGTJe31yqRs0TFMt3H2on2lXIznmhTkbDYf/W+odaTKU= X-Received: by 2002:adf:fe90:: with SMTP id l16mr6870186wrr.221.1559659907969; Tue, 04 Jun 2019 07:51:47 -0700 (PDT) MIME-Version: 1.0 References: <20190531233159.30992-1-sean.j.christopherson@intel.com> <20190531233159.30992-5-sean.j.christopherson@intel.com> In-Reply-To: <20190531233159.30992-5-sean.j.christopherson@intel.com> From: Andy Lutomirski Date: Tue, 4 Jun 2019 07:51:36 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [RFC PATCH 4/9] mm: Introduce vm_ops->mprotect() To: Sean Christopherson Cc: Jarkko Sakkinen , 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 Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 31, 2019 at 4:32 PM Sean Christopherson wrote: > > SGX will use the mprotect() hook to prevent userspace from circumventing > various security checks, i.e. Linux Security Modules. > > 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 > single MAP_SHARED vm_file. 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..50a42364a885 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 (*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..e466ca5e4fe0 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->mprotect) { > + error = vma->vm_ops->mprotect(vma, nstart, tmp, prot); > + if (error) > + goto out; > + } > + > + error = security_file_mprotect(vma, reqprot, prot); > + if (error) > + goto out; > + I think that, if you're going to do it like this, you need to call it mprotect_and_check_security or something. Or you could just add .may_mprotect, which is allowed to fail but, on success, falls through to call security_file_mprotect and mprotect_fixup(). --Andy