All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chester Lin <clin@suse.com>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	zohar@linux.ibm.com, dmitry.kasatkin@gmail.com,
	Jonathan Corbet <corbet@lwn.net>,
	Mark Rutland <mark.rutland@arm.com>,
	Vincenzo Frascino <vincenzo.frascino@arm.com>,
	Sami Tolvanen <samitolvanen@google.com>,
	Masahiro Yamada <masahiroy@kernel.org>,
	Ingo Molnar <mingo@kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-efi <linux-efi@vger.kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	linux-integrity <linux-integrity@vger.kernel.org>,
	Linux Doc Mailing List <linux-doc@vger.kernel.org>,
	"Lee, Chun-Yi" <jlee@suse.com>,
	clin@suse.com
Subject: Re: [PATCH 1/6] efistub: pass uefi secureboot flag via fdt params
Date: Mon, 14 Sep 2020 16:05:22 +0800	[thread overview]
Message-ID: <20200914080522.GA26718@linux-8mug> (raw)
In-Reply-To: <CAMj1kXEXvmO5mrTcKpqYUASBAQB-1=xLa0vg7KwmvOHMjaQ34w@mail.gmail.com>

Hi Ard,

On Fri, Sep 11, 2020 at 06:01:09PM +0300, Ard Biesheuvel wrote:
> On Fri, 4 Sep 2020 at 10:29, Chester Lin <clin@suse.com> wrote:
> >
> > Add a new UEFI parameter: "linux,uefi-secure-boot" in fdt boot params
> > as other architectures have done in their own boot data. For example,
> > the boot_params->secure_boot in x86.
> >
> > Signed-off-by: Chester Lin <clin@suse.com>
> 
> Why do we need this flag? Can't the OS simply check the variable directly?
> 

In fact, there's a difficulty to achieve this.

When linux kernel is booting on ARM, the runtime services are enabled later on.
It's done by arm_enable_runtime_services(), which is registered as an early_initcall.
Before it calls efi_native_runtime_setup(), all EFI runtime callbacks are still
NULL so calling efi.get_variable() will cause NULL pointer dereference.

There's a case that arch_ima_get_secureboot() can be called in early boot stage.
For example, when you try to set "ima_appraise=off" in kernel command line, it's
actually handled early:

[    0.000000] Kernel command line: BOOT_IMAGE=/boot/Image-5.9.0-rc3-9.gdd61cda-
vanilla root=UUID=a88bfb80-8abb-425c-a0f3-ad317465c28b splash=silent mitigations
=auto ignore_loglevel earlycon=pl011,mmio,0x9000000 console=ttyAMA0 ima_appraise=off
[    0.000000] ima: Secure boot enabled: ignoring ima_appraise=off boot parameter option
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)

However EFI services are remapped and enabled afterwards.

[    0.082286] rcu: Hierarchical SRCU implementation.
[    0.089592] Remapping and enabling EFI services.
[    0.097509] smp: Bringing up secondary CPUs ...

Another problem is that efi_rts_wq is created in subsys_initcall so we have to
wait for both EFI services mapping and the workqueue get initiated before calling
efi.get_variable() on ARM.

The only way I can think of is to put a flag via fdt params. May I have your
suggestions? I will appreciate if there's any better approach.

Thanks,
Chester

> > ---
> >  drivers/firmware/efi/libstub/fdt.c | 39 +++++++++++++++++++++++++++++-
> >  1 file changed, 38 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
> > index 11ecf3c4640e..c9a341e4715f 100644
> > --- a/drivers/firmware/efi/libstub/fdt.c
> > +++ b/drivers/firmware/efi/libstub/fdt.c
> > @@ -136,6 +136,10 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
> >         if (status)
> >                 goto fdt_set_fail;
> >
> > +       status = fdt_setprop_var(fdt, node, "linux,uefi-secure-boot", fdt_val32);
> > +       if (status)
> > +               goto fdt_set_fail;
> > +
> >         if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
> >                 efi_status_t efi_status;
> >
> > @@ -199,6 +203,24 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
> >         return EFI_SUCCESS;
> >  }
> >
> > +static efi_status_t update_fdt_secboot(void *fdt, u32 secboot)
> > +{
> > +       int node = fdt_path_offset(fdt, "/chosen");
> > +       u32 fdt_val32;
> > +       int err;
> > +
> > +       if (node < 0)
> > +               return EFI_LOAD_ERROR;
> > +
> > +       fdt_val32 = cpu_to_fdt32(secboot);
> > +
> > +       err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-secure-boot", fdt_val32);
> > +       if (err)
> > +               return EFI_LOAD_ERROR;
> > +
> > +       return EFI_SUCCESS;
> > +}
> > +
> >  struct exit_boot_struct {
> >         efi_memory_desc_t       *runtime_map;
> >         int                     *runtime_entry_count;
> > @@ -208,6 +230,9 @@ struct exit_boot_struct {
> >  static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
> >                                    void *priv)
> >  {
> > +       efi_status_t status;
> > +       enum efi_secureboot_mode secboot_status;
> > +       u32 secboot_var = 0;
> >         struct exit_boot_struct *p = priv;
> >         /*
> >          * Update the memory map with virtual addresses. The function will also
> > @@ -217,7 +242,19 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
> >         efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
> >                         p->runtime_map, p->runtime_entry_count);
> >
> > -       return update_fdt_memmap(p->new_fdt_addr, map);
> > +       status = update_fdt_memmap(p->new_fdt_addr, map);
> > +
> > +       if (status != EFI_SUCCESS)
> > +               return status;
> > +
> > +       secboot_status = efi_get_secureboot();
> > +
> > +       if (secboot_status == efi_secureboot_mode_enabled)
> > +               secboot_var = 1;
> > +
> > +       status = update_fdt_secboot(p->new_fdt_addr, secboot_var);
> > +
> > +       return status;
> >  }
> >
> >  #ifndef MAX_FDT_SIZE
> > --
> > 2.26.1
> >
> 


WARNING: multiple messages have this Message-ID (diff)
From: Chester Lin <clin@suse.com>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
	clin@suse.com, linux-efi <linux-efi@vger.kernel.org>,
	Jonathan Corbet <corbet@lwn.net>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Masahiro Yamada <masahiroy@kernel.org>,
	Linux Doc Mailing List <linux-doc@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	zohar@linux.ibm.com, "Lee, Chun-Yi" <jlee@suse.com>,
	Sami Tolvanen <samitolvanen@google.com>,
	dmitry.kasatkin@gmail.com,
	linux-integrity <linux-integrity@vger.kernel.org>,
	Vincenzo Frascino <vincenzo.frascino@arm.com>,
	Will Deacon <will@kernel.org>, Ingo Molnar <mingo@kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 1/6] efistub: pass uefi secureboot flag via fdt params
Date: Mon, 14 Sep 2020 16:05:22 +0800	[thread overview]
Message-ID: <20200914080522.GA26718@linux-8mug> (raw)
In-Reply-To: <CAMj1kXEXvmO5mrTcKpqYUASBAQB-1=xLa0vg7KwmvOHMjaQ34w@mail.gmail.com>

Hi Ard,

On Fri, Sep 11, 2020 at 06:01:09PM +0300, Ard Biesheuvel wrote:
> On Fri, 4 Sep 2020 at 10:29, Chester Lin <clin@suse.com> wrote:
> >
> > Add a new UEFI parameter: "linux,uefi-secure-boot" in fdt boot params
> > as other architectures have done in their own boot data. For example,
> > the boot_params->secure_boot in x86.
> >
> > Signed-off-by: Chester Lin <clin@suse.com>
> 
> Why do we need this flag? Can't the OS simply check the variable directly?
> 

In fact, there's a difficulty to achieve this.

When linux kernel is booting on ARM, the runtime services are enabled later on.
It's done by arm_enable_runtime_services(), which is registered as an early_initcall.
Before it calls efi_native_runtime_setup(), all EFI runtime callbacks are still
NULL so calling efi.get_variable() will cause NULL pointer dereference.

There's a case that arch_ima_get_secureboot() can be called in early boot stage.
For example, when you try to set "ima_appraise=off" in kernel command line, it's
actually handled early:

[    0.000000] Kernel command line: BOOT_IMAGE=/boot/Image-5.9.0-rc3-9.gdd61cda-
vanilla root=UUID=a88bfb80-8abb-425c-a0f3-ad317465c28b splash=silent mitigations
=auto ignore_loglevel earlycon=pl011,mmio,0x9000000 console=ttyAMA0 ima_appraise=off
[    0.000000] ima: Secure boot enabled: ignoring ima_appraise=off boot parameter option
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)

However EFI services are remapped and enabled afterwards.

[    0.082286] rcu: Hierarchical SRCU implementation.
[    0.089592] Remapping and enabling EFI services.
[    0.097509] smp: Bringing up secondary CPUs ...

Another problem is that efi_rts_wq is created in subsys_initcall so we have to
wait for both EFI services mapping and the workqueue get initiated before calling
efi.get_variable() on ARM.

The only way I can think of is to put a flag via fdt params. May I have your
suggestions? I will appreciate if there's any better approach.

Thanks,
Chester

> > ---
> >  drivers/firmware/efi/libstub/fdt.c | 39 +++++++++++++++++++++++++++++-
> >  1 file changed, 38 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
> > index 11ecf3c4640e..c9a341e4715f 100644
> > --- a/drivers/firmware/efi/libstub/fdt.c
> > +++ b/drivers/firmware/efi/libstub/fdt.c
> > @@ -136,6 +136,10 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
> >         if (status)
> >                 goto fdt_set_fail;
> >
> > +       status = fdt_setprop_var(fdt, node, "linux,uefi-secure-boot", fdt_val32);
> > +       if (status)
> > +               goto fdt_set_fail;
> > +
> >         if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
> >                 efi_status_t efi_status;
> >
> > @@ -199,6 +203,24 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
> >         return EFI_SUCCESS;
> >  }
> >
> > +static efi_status_t update_fdt_secboot(void *fdt, u32 secboot)
> > +{
> > +       int node = fdt_path_offset(fdt, "/chosen");
> > +       u32 fdt_val32;
> > +       int err;
> > +
> > +       if (node < 0)
> > +               return EFI_LOAD_ERROR;
> > +
> > +       fdt_val32 = cpu_to_fdt32(secboot);
> > +
> > +       err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-secure-boot", fdt_val32);
> > +       if (err)
> > +               return EFI_LOAD_ERROR;
> > +
> > +       return EFI_SUCCESS;
> > +}
> > +
> >  struct exit_boot_struct {
> >         efi_memory_desc_t       *runtime_map;
> >         int                     *runtime_entry_count;
> > @@ -208,6 +230,9 @@ struct exit_boot_struct {
> >  static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
> >                                    void *priv)
> >  {
> > +       efi_status_t status;
> > +       enum efi_secureboot_mode secboot_status;
> > +       u32 secboot_var = 0;
> >         struct exit_boot_struct *p = priv;
> >         /*
> >          * Update the memory map with virtual addresses. The function will also
> > @@ -217,7 +242,19 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
> >         efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
> >                         p->runtime_map, p->runtime_entry_count);
> >
> > -       return update_fdt_memmap(p->new_fdt_addr, map);
> > +       status = update_fdt_memmap(p->new_fdt_addr, map);
> > +
> > +       if (status != EFI_SUCCESS)
> > +               return status;
> > +
> > +       secboot_status = efi_get_secureboot();
> > +
> > +       if (secboot_status == efi_secureboot_mode_enabled)
> > +               secboot_var = 1;
> > +
> > +       status = update_fdt_secboot(p->new_fdt_addr, secboot_var);
> > +
> > +       return status;
> >  }
> >
> >  #ifndef MAX_FDT_SIZE
> > --
> > 2.26.1
> >
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-09-14  8:18 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-04  7:28 [PATCH 0/6] add ima_arch support for ARM64 Chester Lin
2020-09-04  7:28 ` Chester Lin
2020-09-04  7:29 ` [PATCH 1/6] efistub: pass uefi secureboot flag via fdt params Chester Lin
2020-09-04  7:29   ` Chester Lin
2020-09-11 15:01   ` Ard Biesheuvel
2020-09-11 15:01     ` Ard Biesheuvel
2020-09-14  8:05     ` Chester Lin [this message]
2020-09-14  8:05       ` Chester Lin
2020-10-05  2:20       ` Chester Lin
2020-10-05  2:20         ` Chester Lin
2020-10-12  8:20         ` Ard Biesheuvel
2020-10-12  8:20           ` Ard Biesheuvel
2020-09-04  7:29 ` [PATCH 2/6] efi/arm: a helper to parse secure boot param in " Chester Lin
2020-09-04  7:29   ` Chester Lin
2020-09-04  7:29 ` [PATCH 3/6] efi: add secure boot flag Chester Lin
2020-09-04  7:29   ` Chester Lin
2020-09-04  7:29 ` [PATCH 4/6] efi/arm: check secure boot status in efi init Chester Lin
2020-09-04  7:29   ` Chester Lin
2020-09-04  7:29 ` [PATCH 5/6] arm64/ima: add ima arch support Chester Lin
2020-09-04  7:29   ` Chester Lin
2020-09-04 11:47   ` Mimi Zohar
2020-09-04 11:47     ` Mimi Zohar
2020-09-04  7:29 ` [PATCH 6/6] docs/arm: add the description of uefi-secure-boot param Chester Lin
2020-09-04  7:29   ` Chester Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200914080522.GA26718@linux-8mug \
    --to=clin@suse.com \
    --cc=ardb@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=corbet@lwn.net \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=jlee@suse.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=masahiroy@kernel.org \
    --cc=mingo@kernel.org \
    --cc=samitolvanen@google.com \
    --cc=vincenzo.frascino@arm.com \
    --cc=will@kernel.org \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.