lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 5 Oct 2019 18:44:08 +0200
From:   Borislav Petkov <bp@...en8.de>
To:     Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
Cc:     linux-kernel@...r.kernel.org, x86@...nel.org,
        linux-sgx@...r.kernel.org, akpm@...ux-foundation.org,
        dave.hansen@...el.com, sean.j.christopherson@...el.com,
        nhorman@...hat.com, npmccallum@...hat.com, serge.ayoun@...el.com,
        shay.katz-zamir@...el.com, haitao.huang@...el.com,
        andriy.shevchenko@...ux.intel.com, tglx@...utronix.de,
        kai.svahn@...el.com, josh@...htriplett.org, luto@...nel.org,
        kai.huang@...el.com, rientjes@...gle.com, cedric.xing@...el.com
Subject: Re: [PATCH v22 09/24] x86/sgx: Add functions to allocate and free
 EPC pages

On Tue, Sep 03, 2019 at 05:26:40PM +0300, Jarkko Sakkinen wrote:
> Add functions for grabbing EPC pages into use:
> 
> * sgx_alloc_page(): Iterate the EPC sections and return the first free
>   page, or ERR_PTR(-ENOMEM) when no free pages are available.
> * __sgx_free_page(): Return the page into uninitialized state and move
>   it back to the corresponding EPC section structure. Issues WARN()
>   when EREMOVE fails.
> * sgx_free_page(): Return the page into uninitialized state and move
>   it back to the corresponding EPC section structure. Returns
>   ENCLS[EREMOVE] error code back to the caller.
> 
> [1] Intel SDM: 40.3 INTELĀ® SGX SYSTEM LEAF FUNCTION REFERENCE
> 
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
> Co-developed-by: Sean Christopherson <sean.j.christopherson@...el.com>
> Signed-off-by: Sean Christopherson <sean.j.christopherson@...el.com>
> ---
>  arch/x86/kernel/cpu/sgx/main.c | 90 ++++++++++++++++++++++++++++++++++
>  arch/x86/kernel/cpu/sgx/sgx.h  |  4 ++
>  2 files changed, 94 insertions(+)
> 
> diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
> index e2317f6e4374..6b4727df72ca 100644
> --- a/arch/x86/kernel/cpu/sgx/main.c
> +++ b/arch/x86/kernel/cpu/sgx/main.c
> @@ -9,6 +9,7 @@
>  #include <linux/sched/signal.h>
>  #include <linux/slab.h>
>  #include "arch.h"
> +#include "encls.h"
>  #include "sgx.h"
>  
>  struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
> @@ -16,6 +17,95 @@ EXPORT_SYMBOL_GPL(sgx_epc_sections);
>  
>  int sgx_nr_epc_sections;
>  
> +static struct sgx_epc_page *sgx_section_get_page(

That fits into 80 cols (oh well, 81) and even if not, a trailing opening
arg brace is ugly.

> +	struct sgx_epc_section *section)
> +{
> +	struct sgx_epc_page *page;
> +
> +	if (!section->free_cnt)
> +		return NULL;
> +
> +	page = list_first_entry(&section->page_list,
> +				struct sgx_epc_page, list);

That fits in 80-cols too. Why break it?

> +	list_del_init(&page->list);
> +	section->free_cnt--;
> +	return page;
> +}
> +
> +/**
> + * sgx_alloc_page - Allocate an EPC page
> + *
> + * Try to grab a page from the free EPC page list.
> + *
> + * Return:
> + *   a pointer to a &struct sgx_epc_page instance,
> + *   -errno on error
> + */
> +struct sgx_epc_page *sgx_alloc_page(void)
> +{
> +	struct sgx_epc_section *section;
> +	struct sgx_epc_page *page;
> +	int i;
> +
> +	for (i = 0; i < sgx_nr_epc_sections; i++) {
> +		section = &sgx_epc_sections[i];
> +		spin_lock(&section->lock);
> +		page = sgx_section_get_page(section);
> +		spin_unlock(&section->lock);
> +
> +		if (page)
> +			return page;
> +	}
> +
> +	return ERR_PTR(-ENOMEM);
> +}
> +EXPORT_SYMBOL_GPL(sgx_alloc_page);

That export gets removed later too. But you know already...

> +
> +/**
> + * __sgx_free_page - Free an EPC page
> + * @page:	pointer a previously allocated EPC page
> + *
> + * EREMOVE an EPC page and insert it back to the list of free pages.
> + *
> + * Return:
> + *   0 on success
> + *   SGX error code if EREMOVE fails
> + */
> +int __sgx_free_page(struct sgx_epc_page *page)
> +{
> +	struct sgx_epc_section *section = sgx_epc_section(page);
> +	int ret;

Shouldn't you be grabbing the lock here already?

Or nothing can happen to that page from another thread after you
ENCLS[EREMOVE] it and before it is added to the ->page_list of the
section?

> +
> +	ret = __eremove(sgx_epc_addr(page));
> +	if (ret)
> +		return ret;
> +
> +	spin_lock(&section->lock);
> +	list_add_tail(&page->list, &section->page_list);
> +	section->free_cnt++;
> +	spin_unlock(&section->lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(__sgx_free_page);
> +
> +/**
> + * sgx_free_page - Free an EPC page and WARN on failure
> + * @page:	pointer to a previously allocated EPC page
> + *
> + * EREMOVE an EPC page and insert it back to the list of free pages, and WARN
> + * if EREMOVE fails.  For use when the call site cannot (or chooses not to)
> + * handle failure, i.e. the page is leaked on failure.
> + */
> +void sgx_free_page(struct sgx_epc_page *page)
> +{
> +	int ret;
> +
> +	ret = __sgx_free_page(page);
> +	WARN(ret > 0, "sgx: EREMOVE returned %d (0x%x)", ret, ret);

That will potentially flood dmesg. Why are we even accommodating such
callers? They either handle the error or they don't get to alloc EPC
pages. There's also __must_check with which you can enforce the error
code checking or we simply don't allow not handling failure. Fullstop.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ