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=-5.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=no 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 C70F9C4346E for ; Fri, 25 Sep 2020 00:01:01 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 46A1B239EC for ; Fri, 25 Sep 2020 00:01:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 46A1B239EC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 36B4F8E0003; Thu, 24 Sep 2020 20:01:00 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 31C058E0001; Thu, 24 Sep 2020 20:01:00 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 20ABB8E0003; Thu, 24 Sep 2020 20:01:00 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0106.hostedemail.com [216.40.44.106]) by kanga.kvack.org (Postfix) with ESMTP id 0BC1D8E0001 for ; Thu, 24 Sep 2020 20:01:00 -0400 (EDT) Received: from smtpin08.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id C64F0181AE862 for ; Fri, 25 Sep 2020 00:00:59 +0000 (UTC) X-FDA: 77299628238.08.pan71_0a0763f27163 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin08.hostedemail.com (Postfix) with ESMTP id B4CBA1819E772 for ; Fri, 25 Sep 2020 00:00:59 +0000 (UTC) X-HE-Tag: pan71_0a0763f27163 X-Filterd-Recvd-Size: 6208 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by imf41.hostedemail.com (Postfix) with ESMTP for ; Fri, 25 Sep 2020 00:00:57 +0000 (UTC) IronPort-SDR: 31GNJ3sH7P2ayPxSAX3IKIdSPHwfz/pN9dr4hlGw/AER8Gu0K/3qMQTGrY4DG7MeGAduWgjEgy Bi1UQ0L6xNzA== X-IronPort-AV: E=McAfee;i="6000,8403,9754"; a="158730338" X-IronPort-AV: E=Sophos;i="5.77,299,1596524400"; d="scan'208";a="158730338" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2020 17:00:55 -0700 IronPort-SDR: 6XZgjc7WoidoEn2AgUju4NOOoLvncOPZVj/1GN8uJrlzkbEiajq7bH/SnRuf173xFcinsr8GKR KJLSYjHSBKjA== X-IronPort-AV: E=Sophos;i="5.77,299,1596524400"; d="scan'208";a="348036152" Received: from sjchrist-coffee.jf.intel.com (HELO linux.intel.com) ([10.54.74.160]) by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2020 17:00:54 -0700 Date: Thu, 24 Sep 2020 17:00:52 -0700 From: Sean Christopherson To: Dave Hansen Cc: Haitao Huang , Jarkko Sakkinen , Andy Lutomirski , X86 ML , linux-sgx@vger.kernel.org, LKML , Linux-MM , Andrew Morton , Matthew Wilcox , Jethro Beekman , Darren Kenny , Andy Shevchenko , asapek@google.com, Borislav Petkov , "Xing, Cedric" , chenalexchen@google.com, Conrad Parker , cyhanish@google.com, "Huang, Haitao" , Josh Triplett , "Huang, Kai" , "Svahn, Kai" , Keith Moyer , Christian Ludloff , Neil Horman , Nathaniel McCallum , Patrick Uiterwijk , David Rientjes , Thomas Gleixner , yaozhangx@google.com Subject: Re: [PATCH v38 10/24] mm: Add vm_ops->mprotect() Message-ID: <20200925000052.GA20333@linux.intel.com> References: <20200923135056.GD5160@linux.intel.com> <20200924192853.GA18826@linux.intel.com> <20200924200156.GA19127@linux.intel.com> <20200924202549.GB19127@linux.intel.com> <20200924230501.GA20095@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) 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: On Thu, Sep 24, 2020 at 04:09:25PM -0700, Dave Hansen wrote: > On 9/24/20 4:05 PM, Sean Christopherson wrote: > > The problem is that enforcing permissions via mprotect() needs to be done > > unconditionally, otherwise we end up with weird behavior where the existence > > of an LSM will change what is/isn't allowed, even if the LSM(s) has no SGX > > policy whatsover. > > Could we make this a bit less abstract, please? > > Could someone point to code or another examples that demonstrates how > the mere existence of an LSM will change what is/isn't allowed? > > I can't seem to wrap my head around it as-is. Without pre-declared permissions, loading and running an enclave would be: ptr = malloc(size); memcpy(ptr, evil_shenanigans, size); ioctl(sgx_fd, ENCLAVE_ADD_PAGE, ptr, size); ... ioctl(sgx_fd, ENCLAVE_INIT); enclave = mmap(sgx_fd, ... PROT_READ); mprotect(enclave, ..., PROT_READ | PROT_EXEC); EENTER; With the existing security_file_mprotect(), an LSM will see: vma->vm_file ~= /dev/sgx/enclave prot = PROT_READ | PROT_EXEC >From a policy perspective, the LSM can't do much because every enclave is backed by /dev/sgx/enclave, and all enclaves need READ and EXEC perms, i.e. a policy can only deny all enclaves or allow enclaves. The solution we came up with is to require userspace to declare the intended permissions at build time so that an LSM hook can be invoked when the source VMA is availble, e.g. in this example, the LSM would see that the process is loading executable code into an enclave from an anonymous VMA: ptr = malloc(size); memcpy(ptr, evil_shenanigans, size); ioctl(sgx_fd, ENCLAVE_ADD_PAGE, SGX_PROT_READ | SGX_PROT_EXEC, ptr, size); { ret = security_enclave_load(ptr, prot); if (ret) return ret; enclave_page->declared_prot = prot; } ... ioctl(sgx_fd, ENCLAVE_INIT); and then enforce the declared perms via ->mprotect() enclave = mmap(sgx_fd, ... PROT_READ); mprotect(enclave, ..., PROT_READ | PROT_EXEC); | -> sgx_mprotect(...) { if (~enclave_page->declared_prot & prot) return -EACCES; } EENTER; So the above would be allowed, but this would fail (irrespective of LSM behavior): ptr = malloc(size); memcpy(ptr, evil_shenanigans, size); ioctl(sgx_fd, ENCLAVE_ADD_PAGE, SGX_PROT_READ, ptr, size); ... ioctl(sgx_fd, ENCLAVE_INIT); enclave = mmap(sgx_fd, ... PROT_READ); mprotect(enclave, ..., PROT_READ | PROT_EXEC); My concern is that if we merge this ioctl(sgx_fd, ENCLAVE_ADD_PAGE, SGX_PROT_READ | SGX_PROT_EXEC, ptr, size); without ->mprotect(), we can't actually enforce the declared protections. And if we drop the field altogether: ioctl(sgx_fd, ENCLAVE_ADD_PAGE, ptr, size); then we can't implement security_enclave_load().