mbox series

[WIP,RFC,0/6] Generic Firmware Variable Filesystem

Message ID 20190520062553.14947-1-dja@axtens.net (mailing list archive)
Headers show
Series Generic Firmware Variable Filesystem | expand

Message

Daniel Axtens May 20, 2019, 6:25 a.m. UTC
Hi all,

As PowerNV moves towards secure boot, we need a place to put secure
variables. One option that has been canvassed is to make our secure
variables look like EFI variables. This is an early sketch of another
approach where we create a generic firmware variable file system,
fwvarfs, and an OPAL Secure Variable backend for it.

In short, platforms provide a simple backend that can interface with
the hardware, and fwvarfs deals with translating that into a
filesystem that you can use. Almost all of the hard work is done by
kernfs: fwvarfs provides a pretty thin layer on top of that to make
backends a simple as possible.

Behaviour and the API is documented in Documentation/filesystems/fwvarfs.txt

To demonstrate the concept, a fully functional memory-based backend is
provided, and a read-only but userspace-compatible EFI backend.

For OPAL secure variables, I have taken Claudio's commit, tweaked it
to apply to linux-next, replaced all the EFI support with a generic
API, and then written a backend against that. There's a coming version
from Claudio that moves the opal calls towards a simple key/value
interface rather than (name, vendor) pairs - I haven't waited for
that: this is really just to demonstrate that it could be done rather
than an attempt to get mergable code.  It is also compile tested only
as I haven't yet set myself up with a test machine.

The patches are a bit rough, and there are a number of outstanding
TODOs sprinkled in everywhere. The idea is just to do a proof of
concept to inform our discussions:

 - Is this the sort of approach you'd like (generic vs specific)?
 
 - Does the backend API make sense?
 
 - Is the use of kernfs the correct decision, or is it potentially too
   limiting? (e.g. no ability to do case-insensitivity like efivarfs)

 - Is assuming flat fwvars correct or is there a firmware with a
   hierarchical structure?

Regards,
Daniel

Claudio Carvalho (1):
  powerpc/powernv: Add support for OPAL secure variables

Daniel Axtens (5):
  kernfs: add create() and unlink() hooks
  fwvarfs: a generic firmware variable filesystem
  fwvarfs: efi backend
  powerpc/powernv: Remove EFI support for OPAL secure variables
  fwvarfs: Add opal_secvar backend

 Documentation/filesystems/fwvarfs.txt        | 154 ++++++++++
 arch/powerpc/include/asm/opal-api.h          |   6 +-
 arch/powerpc/include/asm/opal-secvar.h       |  58 ++++
 arch/powerpc/include/asm/opal.h              |  10 +
 arch/powerpc/platforms/powernv/Kconfig       |   8 +
 arch/powerpc/platforms/powernv/Makefile      |   1 +
 arch/powerpc/platforms/powernv/opal-call.c   |   4 +
 arch/powerpc/platforms/powernv/opal-secvar.c | 121 ++++++++
 fs/Kconfig                                   |   1 +
 fs/Makefile                                  |   1 +
 fs/fwvarfs/Kconfig                           |  47 +++
 fs/fwvarfs/Makefile                          |  10 +
 fs/fwvarfs/efi.c                             | 177 +++++++++++
 fs/fwvarfs/fwvarfs.c                         | 294 +++++++++++++++++++
 fs/fwvarfs/fwvarfs.h                         | 124 ++++++++
 fs/fwvarfs/mem.c                             | 113 +++++++
 fs/fwvarfs/opal_secvar.c                     | 218 ++++++++++++++
 fs/kernfs/dir.c                              |  54 ++++
 include/linux/kernfs.h                       |   3 +
 include/uapi/linux/magic.h                   |   1 +
 20 files changed, 1404 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/filesystems/fwvarfs.txt
 create mode 100644 arch/powerpc/include/asm/opal-secvar.h
 create mode 100644 arch/powerpc/platforms/powernv/opal-secvar.c
 create mode 100644 fs/fwvarfs/Kconfig
 create mode 100644 fs/fwvarfs/Makefile
 create mode 100644 fs/fwvarfs/efi.c
 create mode 100644 fs/fwvarfs/fwvarfs.c
 create mode 100644 fs/fwvarfs/fwvarfs.h
 create mode 100644 fs/fwvarfs/mem.c
 create mode 100644 fs/fwvarfs/opal_secvar.c

Comments

Nayna May 31, 2019, 4:04 a.m. UTC | #1
On 05/20/2019 02:25 AM, Daniel Axtens wrote:
> Hi all,
>
> As PowerNV moves towards secure boot, we need a place to put secure
> variables. One option that has been canvassed is to make our secure
> variables look like EFI variables. This is an early sketch of another
> approach where we create a generic firmware variable file system,
> fwvarfs, and an OPAL Secure Variable backend for it.

Is there a need of new filesystem ? I am wondering why can't these be 
exposed via sysfs / securityfs ?
Probably, something like... /sys/firmware/secureboot or 
/sys/kernel/security/secureboot/  ?

Also, it sounds like this is needed only for secure firmware variables 
and does not include
other firmware variables which are not security relevant ? Is that 
correct understanding ?

Thanks & Regards,
       - Nayna
Daniel Axtens June 3, 2019, 6:04 a.m. UTC | #2
Hi Nayna,

>> As PowerNV moves towards secure boot, we need a place to put secure
>> variables. One option that has been canvassed is to make our secure
>> variables look like EFI variables. This is an early sketch of another
>> approach where we create a generic firmware variable file system,
>> fwvarfs, and an OPAL Secure Variable backend for it.
>
> Is there a need of new filesystem ? I am wondering why can't these be 
> exposed via sysfs / securityfs ?
> Probably, something like... /sys/firmware/secureboot or 
> /sys/kernel/security/secureboot/  ?

I suppose we could put secure variables in sysfs, but I'm not sure
that's what sysfs was intended for. I understand sysfs as "a
filesystem-based view of kernel objects" (from
Documentation/filesystems/configfs/configfs.txt), and I don't think a
secure variable is really a kernel object in the same way most other
things in sysfs are... but I'm open to being convinced.

securityfs seems to be reserved for LSMs, I don't think we can put
things there.

My hope with fwvarfs is to provide a generic place for firmware
variables so that we don't need to expand the list of firmware-specific
filesystems beyond efivarfs. I am also aiming to make things simple to
use so that people familiar with firmware don't also have to become
familiar with filesystem code in order to expose firmware variables to
userspace.

> Also, it sounds like this is needed only for secure firmware variables 
> and does not include
> other firmware variables which are not security relevant ? Is that 
> correct understanding ?

The primary use case at the moment - OPAL secure variables - is security
focused because the current OPAL secure variable design stores and
manipulates secure variables separately from the rest of nvram. This
isn't an inherent feature of fwvarfs.

fwvarfs can also be used for variables that are not security relevant as
well. For example, with the EFI backend (patch 3), both secure and
insecure variables can be read.

Regards,
Daniel
Greg Kroah-Hartman June 3, 2019, 7:29 a.m. UTC | #3
On Mon, Jun 03, 2019 at 04:04:32PM +1000, Daniel Axtens wrote:
> Hi Nayna,
> 
> >> As PowerNV moves towards secure boot, we need a place to put secure
> >> variables. One option that has been canvassed is to make our secure
> >> variables look like EFI variables. This is an early sketch of another
> >> approach where we create a generic firmware variable file system,
> >> fwvarfs, and an OPAL Secure Variable backend for it.
> >
> > Is there a need of new filesystem ? I am wondering why can't these be 
> > exposed via sysfs / securityfs ?
> > Probably, something like... /sys/firmware/secureboot or 
> > /sys/kernel/security/secureboot/  ?
> 
> I suppose we could put secure variables in sysfs, but I'm not sure
> that's what sysfs was intended for. I understand sysfs as "a
> filesystem-based view of kernel objects" (from
> Documentation/filesystems/configfs/configfs.txt), and I don't think a
> secure variable is really a kernel object in the same way most other
> things in sysfs are... but I'm open to being convinced.

What makes them more "secure" than anything else that is in sysfs today?
I didn't see anything in this patchset that provided "additional
security", did I miss it?

> securityfs seems to be reserved for LSMs, I don't think we can put
> things there.

Yeah, I wouldn't mess with that.

I would just recommend putting this in sysfs.  Make a new subsystem
(i.e. class) and away you go.

> My hope with fwvarfs is to provide a generic place for firmware
> variables so that we don't need to expand the list of firmware-specific
> filesystems beyond efivarfs. I am also aiming to make things simple to
> use so that people familiar with firmware don't also have to become
> familiar with filesystem code in order to expose firmware variables to
> userspace.

Why would anyone need to be writing new code to firmware variables that
makes it any different from any other kernel change?

> > Also, it sounds like this is needed only for secure firmware variables 
> > and does not include
> > other firmware variables which are not security relevant ? Is that 
> > correct understanding ?
> 
> The primary use case at the moment - OPAL secure variables - is security
> focused because the current OPAL secure variable design stores and
> manipulates secure variables separately from the rest of nvram. This
> isn't an inherent feature of fwvarfs.

Again, why not just put it in sysfs please?

> fwvarfs can also be used for variables that are not security relevant as
> well. For example, with the EFI backend (patch 3), both secure and
> insecure variables can be read.

I don't remember why efi variables were not put in sysfs, I think there
was some reasoning behind it originally.  Perhaps look in the linux-efi
archives.

thanks,

greg k-h
Daniel Axtens June 3, 2019, 11:56 p.m. UTC | #4
Hi Greg,

>> >> As PowerNV moves towards secure boot, we need a place to put secure
>> >> variables. One option that has been canvassed is to make our secure
>> >> variables look like EFI variables. This is an early sketch of another
>> >> approach where we create a generic firmware variable file system,
>> >> fwvarfs, and an OPAL Secure Variable backend for it.
>> >
>> > Is there a need of new filesystem ? I am wondering why can't these be 
>> > exposed via sysfs / securityfs ?
>> > Probably, something like... /sys/firmware/secureboot or 
>> > /sys/kernel/security/secureboot/  ?
>> 
>> I suppose we could put secure variables in sysfs, but I'm not sure
>> that's what sysfs was intended for. I understand sysfs as "a
>> filesystem-based view of kernel objects" (from
>> Documentation/filesystems/configfs/configfs.txt), and I don't think a
>> secure variable is really a kernel object in the same way most other
>> things in sysfs are... but I'm open to being convinced.
>
> What makes them more "secure" than anything else that is in sysfs today?
> I didn't see anything in this patchset that provided "additional
> security", did I miss it?

You're right, there's no additional security. What I should have said
was that I didn't think that _firmware_ variables were kernel objects in
the same way that other things in sysfs are. Having read the rest of
your reply it seems I'm mistaken on this.

> I would just recommend putting this in sysfs.  Make a new subsystem
> (i.e. class) and away you go.
>
>> My hope with fwvarfs is to provide a generic place for firmware
>> variables so that we don't need to expand the list of firmware-specific
>> filesystems beyond efivarfs. I am also aiming to make things simple to
>> use so that people familiar with firmware don't also have to become
>> familiar with filesystem code in order to expose firmware variables to
>> userspace.

>> fwvarfs can also be used for variables that are not security relevant as
>> well. For example, with the EFI backend (patch 3), both secure and
>> insecure variables can be read.
>
> I don't remember why efi variables were not put in sysfs, I think there
> was some reasoning behind it originally.  Perhaps look in the linux-efi
> archives.

I'll have a look: I suspect the appeal of efivarfs is that it allows for
things like non-case-sensitive matching on the GUID part of the filename
while retaining case-sensitivity on the part of the filename
representing the variable name.

As suggested, I'll try a sysfs class. I think that will allow me to
kill off most of the abstraction layer too. Thanks for the input.

Regards,
Daniel

>
> thanks,
>
> greg k-h
Nayna June 4, 2019, 8:01 p.m. UTC | #5
On 06/03/2019 07:56 PM, Daniel Axtens wrote:
>
>> I would just recommend putting this in sysfs.  Make a new subsystem
>> (i.e. class) and away you go.
>>
>>> My hope with fwvarfs is to provide a generic place for firmware
>>> variables so that we don't need to expand the list of firmware-specific
>>> filesystems beyond efivarfs. I am also aiming to make things simple to
>>> use so that people familiar with firmware don't also have to become
>>> familiar with filesystem code in order to expose firmware variables to
>>> userspace.
>>> fwvarfs can also be used for variables that are not security relevant as
>>> well. For example, with the EFI backend (patch 3), both secure and
>>> insecure variables can be read.
>> I don't remember why efi variables were not put in sysfs, I think there
>> was some reasoning behind it originally.  Perhaps look in the linux-efi
>> archives.
> I'll have a look: I suspect the appeal of efivarfs is that it allows for
> things like non-case-sensitive matching on the GUID part of the filename
> while retaining case-sensitivity on the part of the filename
> representing the variable name.

It seems efivars were first implemented in sysfs and then later 
separated out as efivarfs.
Refer - Documentation/filesystems/efivarfs.txt.

So, the reason wasn't that sysfs should not be used for exposing 
firmware variables,
but for the size limitations which seems to come from UEFI Specification.

Is this limitation valid for the new requirement of secure variables ?

Copying Matthew who can give us more insights...

Thanks & Regards,
      - Nayna
Matthew Garrett June 4, 2019, 8:05 p.m. UTC | #6
On Tue, Jun 4, 2019 at 1:01 PM Nayna <nayna@linux.vnet.ibm.com> wrote:
> It seems efivars were first implemented in sysfs and then later
> separated out as efivarfs.
> Refer - Documentation/filesystems/efivarfs.txt.
>
> So, the reason wasn't that sysfs should not be used for exposing
> firmware variables,
> but for the size limitations which seems to come from UEFI Specification.
>
> Is this limitation valid for the new requirement of secure variables ?

I don't think the size restriction is an issue now, but there's a lot
of complex semantics around variable deletion and immutability that
need to be represented somehow.
Nayna June 4, 2019, 8:33 p.m. UTC | #7
On 06/03/2019 03:29 AM, Greg KH wrote:
> On Mon, Jun 03, 2019 at 04:04:32PM +1000, Daniel Axtens wrote:
>> Hi Nayna,
>>
>>>> As PowerNV moves towards secure boot, we need a place to put secure
>>>> variables. One option that has been canvassed is to make our secure
>>>> variables look like EFI variables. This is an early sketch of another
>>>> approach where we create a generic firmware variable file system,
>>>> fwvarfs, and an OPAL Secure Variable backend for it.
>>> Is there a need of new filesystem ? I am wondering why can't these be
>>> exposed via sysfs / securityfs ?
>>> Probably, something like... /sys/firmware/secureboot or
>>> /sys/kernel/security/secureboot/  ?
>> I suppose we could put secure variables in sysfs, but I'm not sure
>> that's what sysfs was intended for. I understand sysfs as "a
>> filesystem-based view of kernel objects" (from
>> Documentation/filesystems/configfs/configfs.txt), and I don't think a
>> secure variable is really a kernel object in the same way most other
>> things in sysfs are... but I'm open to being convinced.
> What makes them more "secure" than anything else that is in sysfs today?
> I didn't see anything in this patchset that provided "additional
> security", did I miss it?
>
>> securityfs seems to be reserved for LSMs, I don't think we can put
>> things there.
> Yeah, I wouldn't mess with that.

Thanks Greg for clarifying!! I am curious, the TPM exposes the BIOS event log to userspace via securityfs. Is there a reason for not exposing these security variables to userspace via securityfs as well?

Thanks & Regards,
    - Nayna
Greg Kroah-Hartman June 5, 2019, 6:14 a.m. UTC | #8
On Tue, Jun 04, 2019 at 04:33:14PM -0400, Nayna wrote:
> 
> 
> On 06/03/2019 03:29 AM, Greg KH wrote:
> > On Mon, Jun 03, 2019 at 04:04:32PM +1000, Daniel Axtens wrote:
> > > Hi Nayna,
> > > 
> > > > > As PowerNV moves towards secure boot, we need a place to put secure
> > > > > variables. One option that has been canvassed is to make our secure
> > > > > variables look like EFI variables. This is an early sketch of another
> > > > > approach where we create a generic firmware variable file system,
> > > > > fwvarfs, and an OPAL Secure Variable backend for it.
> > > > Is there a need of new filesystem ? I am wondering why can't these be
> > > > exposed via sysfs / securityfs ?
> > > > Probably, something like... /sys/firmware/secureboot or
> > > > /sys/kernel/security/secureboot/  ?
> > > I suppose we could put secure variables in sysfs, but I'm not sure
> > > that's what sysfs was intended for. I understand sysfs as "a
> > > filesystem-based view of kernel objects" (from
> > > Documentation/filesystems/configfs/configfs.txt), and I don't think a
> > > secure variable is really a kernel object in the same way most other
> > > things in sysfs are... but I'm open to being convinced.
> > What makes them more "secure" than anything else that is in sysfs today?
> > I didn't see anything in this patchset that provided "additional
> > security", did I miss it?
> > 
> > > securityfs seems to be reserved for LSMs, I don't think we can put
> > > things there.
> > Yeah, I wouldn't mess with that.
> 
> Thanks Greg for clarifying!! I am curious, the TPM exposes the BIOS
> event log to userspace via securityfs. Is there a reason for not
> exposing these security variables to userspace via securityfs as well?

securityfs is for LSMs to use.  If the TPM drivers also use it, well,
that's between those authors and the securityfs developers.

BIOS/firmware variables are a much different thing than a TPM log.

thanks,

greg k-h
Greg Kroah-Hartman June 5, 2019, 8:13 a.m. UTC | #9
On Tue, Jun 04, 2019 at 01:05:45PM -0700, Matthew Garrett wrote:
> On Tue, Jun 4, 2019 at 1:01 PM Nayna <nayna@linux.vnet.ibm.com> wrote:
> > It seems efivars were first implemented in sysfs and then later
> > separated out as efivarfs.
> > Refer - Documentation/filesystems/efivarfs.txt.
> >
> > So, the reason wasn't that sysfs should not be used for exposing
> > firmware variables,
> > but for the size limitations which seems to come from UEFI Specification.
> >
> > Is this limitation valid for the new requirement of secure variables ?
> 
> I don't think the size restriction is an issue now, but there's a lot
> of complex semantics around variable deletion and immutability that
> need to be represented somehow.

Ah, yeah, that's the reason it would not work in sysfs, forgot all about
that, thanks.

greg k-h