Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp711842pxk; Thu, 24 Sep 2020 17:04:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyTPsn0NUtnvGihF3WUYyDIYr/87g2VaAv54GPQakuF9v01SqZtiJOM14hnIFHRs2TL11kJ X-Received: by 2002:a17:906:6884:: with SMTP id n4mr174250ejr.50.1600992256380; Thu, 24 Sep 2020 17:04:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600992256; cv=none; d=google.com; s=arc-20160816; b=NaXM2lOnTGvPHS6UlhSWUAFW0oxYyMCSaILSfCmBCuvhjdOOM0rmjFpXl34DVyBTs7 0ClIGZM6RXibIitLKkIbfwV42s1g3ACw9i9dLaiVyXvO79b9eND01DwoxqSwdgwQH/qS oayZKuHNSAVzfvZCRjSHnL4S27xHfmK0A40SbIKqFeb978d2jqkeZMVkCTvgPsa06YMK xMF2RgWOKIIGA4QLifBREXjy6+6FNx6QjwdKxgjXJmrK635vbUOt3YpBk0FagmTfZ+bK 1O6FlS203VZrXTQG45ij+w1lfgLZXq9qQ/SMWp46qC96GO1VfeX8MgRr1Ahps5z96nQz vVCw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :ironport-sdr:ironport-sdr; bh=ThcZdYCOs3O8+KXfZQpzX8Y4c9EQzuxlKUpxdhnYU4c=; b=ddnl00dMKsEVIjGFjcTOxxn3Um+PBzgLfiiFmP6puefv00fpqiONW5q/F0+mVFEKIn CCixdbK1Hb/OhcbwIl/SvAR0u0Mhtt5E9RuRi3FPnBIkh2Q4rtlGu3xd3i5vQiVt5j/H JO57iYJzM0p8cAKbN22tHT4SQngLVc0TYBIccsVcd3R9OWSDQTQ0uuNO3cXuclD6ejfa ppNe1h102/URHYkBIeEbTM1bvmkAyC6KEO91JtiDdwKYsoNXSGg6Pi52ayzfHsI73T3/ s+HfRnHXrgV2N4Kf78+BKYCRJHVeJRju8wGM/IHgh8dF4Rr9yKm4sdezxmtKeXyF4hKV 1WXg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id ci27si846607ejc.373.2020.09.24.17.03.52; Thu, 24 Sep 2020 17:04:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1726706AbgIYAA4 (ORCPT + 99 others); Thu, 24 Sep 2020 20:00:56 -0400 Received: from mga12.intel.com ([192.55.52.136]:37670 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726662AbgIYAA4 (ORCPT ); Thu, 24 Sep 2020 20:00:56 -0400 IronPort-SDR: zLY5OmMdNpo7wJWsvwtdB3bFt89fcWz5Lx84rqdgmDeorUREzwEnp7YtAdv3nFOjLhg9u1cLSa ZDsEK31bUKGw== X-IronPort-AV: E=McAfee;i="6000,8403,9754"; a="140813204" X-IronPort-AV: E=Sophos;i="5.77,299,1596524400"; d="scan'208";a="140813204" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga106.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) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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().