Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp5861380ybi; Tue, 4 Jun 2019 13:39:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqz2x8uIiOAu3BMcmBCg65GcDNtC0quOGLrG5+gOBfekJaNlD8UIUlOLk3DCBgwV+FxasyJq X-Received: by 2002:a62:5306:: with SMTP id h6mr41396524pfb.29.1559680742089; Tue, 04 Jun 2019 13:39:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559680742; cv=none; d=google.com; s=arc-20160816; b=f0ZCdGw4wI7QfjP2r2QxU6doFXlT+GsgAlcbtOzKy79KBbByqaMYg2A5gvo68Q2RQP 4oJ+Xq/DtEGW97y0D4SulI9ko1OyV/qTzqaT4M7JXGdkqYwnss/4xusvd7ObdxVvj3CC KyhcdMAF7mvYEBLZWBhHWHd+EhB3Ok2fEh9mho66v8R0DSm/JNkTwH4abk5keFc8Xdlg tO2GBXd0GgYs8N8DJVVWceeKYsI50mbTqtN+lvFwy9KAKO0vI/yvDVekRtRzgXF1cluf wwooYk1aVnvQz+33WskF/mTANODH16mknI4Bv0EDpZoq2/D3z123EMGhawfAQevvtRXM opkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=1FrAECEZEaHo3LinZ8VraXbt2yLQnH4Vtst4F/akmss=; b=RbGb0ohYEHEVp7oagDZgBQZVKKcC740LsLxpL7S7XkDGkfJoYfoFvQEwq2fBZugnbz qJIwxA01M+ClXR2NNEGjsOuuZTIhKZn8HGs7rp8WPXkgeObMbakI/zZ8nsZ3tuiAVIzs AUaNr1ZAglg9iL527i/DQe7IVuKOWODx0GPdIhkumqSgCw+ojevCrOwEd/hWOODoxLDY Br2fR08YROI7gkIGvP9KfSb+2Dq5VnSYGYLy362Fvsp/ye6RNT0gIxLjY3Mm1xKrWnOx /5sHk47Ir545r98YhJVnUVme0l2gkA230iJr65H3Lhs1VZKATnWH2THwjZtQM5pcKtkP roow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=2HRcWilz; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i197si21885348pgd.80.2019.06.04.13.38.46; Tue, 04 Jun 2019 13:39:02 -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; dkim=pass header.i=@kernel.org header.s=default header.b=2HRcWilz; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726723AbfFDUhZ (ORCPT + 99 others); Tue, 4 Jun 2019 16:37:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:33726 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726589AbfFDUhY (ORCPT ); Tue, 4 Jun 2019 16:37:24 -0400 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (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 D71E020B1F for ; Tue, 4 Jun 2019 20:29:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559680163; bh=cFvISWqZtenk/itmER7f+dDnKlLEKMgxPk2A4pPepQo=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=2HRcWilzppDkhdZc4TaBjrV5UIkT55QL43VjaSXEiVplRVpcAxBwNkDcNug+37B+Y t9fbgeUJZIdsTchPZypFGwlhJLgpyuR/aNqVnzXAOqtuoX8oEoU5j1y8GrjbLYqYJn ogGs6TSf8PXi12+IZT5rOfJH6kFTruNBQ6p9qQWM= Received: by mail-wr1-f51.google.com with SMTP id d18so17193533wrs.5 for ; Tue, 04 Jun 2019 13:29:22 -0700 (PDT) X-Gm-Message-State: APjAAAUVFs+pyuSWaSWiCpABGufl3Du2PpFF6GX2DkNt6icZ3v/Ba7q8 djqTE2/o55YnLOJtENJnxXgVbD4zhEdpcX+nwkekCQ== X-Received: by 2002:adf:f2c8:: with SMTP id d8mr92723wrp.221.1559680161582; Tue, 04 Jun 2019 13:29:21 -0700 (PDT) MIME-Version: 1.0 References: <20190531233159.30992-1-sean.j.christopherson@intel.com> <20190531233159.30992-9-sean.j.christopherson@intel.com> In-Reply-To: <20190531233159.30992-9-sean.j.christopherson@intel.com> From: Andy Lutomirski Date: Tue, 4 Jun 2019 13:29:10 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [RFC PATCH 8/9] LSM: x86/sgx: Introduce ->enclave_load() hook for Intel SGX 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: > > enclave_load() is roughly analogous to the existing file_mprotect(). > > Due to the nature of SGX and its Enclave Page Cache (EPC), all enclave > VMAs are backed by a single file, i.e. /dev/sgx/enclave, that must be > MAP_SHARED. Furthermore, all enclaves need read, write and execute > VMAs. As a result, file_mprotect() does not provide any meaningful > security for enclaves since an LSM can only deny/grant access to the > EPC as a whole. > > security_enclave_load() is called when SGX is first loading an enclave > page, i.e. copying a page from normal memory into the EPC. The notable > difference from file_mprotect() is the allowed_prot parameter, which > is essentially an SGX-specific version of a VMA's MAY_{READ,WRITE,EXEC} > flags. The purpose of allowed_prot is to enable checks such as > SELinux's FILE__EXECMOD permission without having to track and update > VMAs across multiple mm structs, i.e. SGX can ensure userspace doesn't > overstep its bounds simply by restricting an enclave VMA's protections > by vetting what is maximally allowed during build time. > > An alternative to the allowed_prot approach would be to use an enclave's > SIGSTRUCT (a smallish structure that can uniquely identify an enclave) > as a proxy for the enclave. For example, SGX could take and hold a > reference to the file containing the SIGSTRUCT (if it's in a file) and > call security_enclave_load() during mprotect(). While the SIGSTRUCT > approach would provide better precision, the actual value added was > deemed to be negligible. On the other hand, pinning a file for the > lifetime of the enclave is ugly, and essentially caching LSM policies > in each page's allowed_prot avoids having to make an extra LSM upcall > during mprotect(). > > Note, extensive discussion yielded no sane alternative to some form of > SGX specific LSM hook[1]. > > [1] https://lkml.kernel.org/r/CALCETrXf8mSK45h7sTK5Wf+pXLVn=Bjsc_RLpgO-h-qdzBRo5Q@mail.gmail.com > > Signed-off-by: Sean Christopherson > --- > arch/x86/kernel/cpu/sgx/driver/ioctl.c | 14 +++++++++----- > include/linux/lsm_hooks.h | 16 ++++++++++++++++ > include/linux/security.h | 2 ++ > security/security.c | 8 ++++++++ > 4 files changed, 35 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c > index 5f71be7cbb01..260417ecbcff 100644 > --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c > +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -580,21 +581,24 @@ static int sgx_encl_page_protect(unsigned long src, unsigned long prot, > unsigned long *allowed_prot) > { > struct vm_area_struct *vma; > + int ret = 0; > > - if (!(*allowed_prot & VM_EXEC)) > + if (!(*allowed_prot & VM_EXEC) && !IS_ENABLED(CONFIG_SECURITY)) > goto do_check; > > down_read(¤t->mm->mmap_sem); > vma = find_vma(current->mm, src); > if (!vma || (vma->vm_file && path_noexec(&vma->vm_file->f_path))) > *allowed_prot &= ~VM_EXEC; > +#ifdef CONFIG_SECURITY > + ret = security_enclave_load(vma, prot, allowed_prot); > +#endif > up_read(¤t->mm->mmap_sem); > > do_check: > - if (prot & ~*allowed_prot) > - return -EACCES; > - > - return 0; > + if (!ret && (prot & ~*allowed_prot)) > + ret = -EACCES; > + return ret; > } > > static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > index 47f58cfb6a19..0562775424a0 100644 > --- a/include/linux/lsm_hooks.h > +++ b/include/linux/lsm_hooks.h > @@ -1446,6 +1446,14 @@ > * @bpf_prog_free_security: > * Clean up the security information stored inside bpf prog. > * > + * Security hooks for Intel SGX enclaves. > + * > + * @enclave_load: > + * On success, returns 0 and optionally adjusts @allowed_prot > + * @vma: the source memory region of the enclave page being loaded. > + * @prot: the initial protection of the enclave page. What do you mean "initial"? The page is always mapped PROT_NONE when this is called, right? I feel like I must be missing something here.