LKML Archive on lore.kernel.org
 help / color / Atom feed
From: "Luis R. Rodriguez" <mcgrof@kernel.org>
To: "AKASHI, Takahiro" <takahiro.akashi@linaro.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Mimi Zohar <zohar@linux.vnet.ibm.com>,
	Jan Blunck <jblunck@infradead.org>,
	Julia Lawall <julia.lawall@lip6.fr>,
	David Howells <dhowells@redhat.com>,
	Andy Lutomirski <luto@kernel.org>,
	David Woodhouse <dwmw2@infradead.org>,
	Marcus Meissner <meissner@suse.de>, Gary Lin <GLin@suse.com>,
	Josh Triplett <josh@joshtriplett.org>,
	James Bottomley <James.Bottomley@hansenpartnership.com>,
	Peter Jones <pjones@redhat.com>,
	"Luis R. Rodriguez" <mcgrof@kernel.org>,
	linux-security-module@vger.kernel.org,
	gnomes@lxorguk.ukuu.org.uk, linux-efi <linux-efi@vger.kernel.org>,
	linux-kernel@vger.kernel.org, Matthew Garrett <mjg59@google.com>
Subject: Re: Firmware signing -- Re: [PATCH 00/27] security, efi: Add kernel lockdown
Date: Fri, 10 Nov 2017 02:46:41 +0100
Message-ID: <20171110014641.GO22894@wotan.suse.de> (raw)
In-Reply-To: <20171109014841.GF7859@linaro.org>

On Thu, Nov 09, 2017 at 10:48:43AM +0900, AKASHI, Takahiro wrote:
> On Wed, Nov 08, 2017 at 08:46:26PM +0100, Luis R. Rodriguez wrote:
> > But perhaps I'm not understanding the issue well, let me know.
> 
> My point is quite simple:
> my_deviceA_init() {
>         err = request_firmware(&fw, "deviceA"); <--- (a)
>         if (err)
>                 goto err_request;
> 
>         err = verify_firmware(fw);  <--- (b)
>         if (err)
>                 goto err_verify;
> 
>         load_fw_to_deviceA(fw);     <--- (c)
>         ...
> }
> 
> As legacy device drivers does not have (b), there is no chance to
> prevent loading a firmware at (c) for locked-down kernel.

Ah, I think your example requires another piece of code to make it clearer.
Here is an example legacy driver:

my_legacy_deviceB_init() {
        err = request_firmware(&fw, "deviceB"); <--- (a)
        if (err)
                goto err_request;

        load_fw_to_deviceA(fw);     <--- (c)
        ...
}

There is no verify_firmware() call here, and as such the approach Linus
suggested a while ago cannot possibly fail on a "locked down kernel", unless
*very* legacy API call gets a verify_firmware() sprinkled.

One sensible thing to say here is then that all request_firmware() calls should
just fail on a "locked down kernel", however if this were true then even calls
which *did* issue a subsequent verify_firmware() would fail earlier therefore
making verify_firmware() pointless on new drivers.

Is that what you meant?

A long time ago we discussed similar default mechanisms, so its worth
re-iterating conclusions done before. The only difference with our current
discussion is that the latest proposed mechanism by Linus for firmware signing
was to consider a verify_firmware() so we can upkeep a functional API approach
to adding support for firmware signing.

What you are asking is what are default mechanism should be, and how do we
*ensure* this works using the functional API approach. We had ironed out
what the default mechanism should have been a while ago, not so much the
later as the firmware API has been in a state of flux. I'll provide pointers
to discussions around the default policy so that none of this is lost and
so that how we end up doing things is well understood later. We can try
to also hash out how to make this work then.

David Woodhouse has long recommended that a 'defult key' should only be last
resort [0], on that same email he also had suggested that since we could end up
supporting different signing schemes it may be best to support cryptographic
requirements (cert identifier or hash) from the start. James Bottomley has
recommended that the default behaviour can only be left up to "system policy".

A "system policy" is exactly what "kernel lockdown" is. David's email contained
a man page which stipulated that the policy that this type of system would follow
*is* to reject unsigned firmware. He and others may want to review if they indeed
wanted to follow this path in lieu of this email.

Even if one is not using a "kernel lockdown" system policy, we can consider the
old schemes discussed for firmware singing. In 2015 I first proposed a simple
signing scheme firmware signing which mimics the Linux module signing scheme
[2].  The issues with "purpose of a key" was well hashed out (a firmware key
should only work for firmware and only for the firmware it was designed for,
etc) and later iterations considered this thanks to Andy.

In this scheme, the default system policy depended on what kernel configuration
option your system had been built with, and matching the module signing scheme
we had:

	o CONFIG_FIRMWARE_SIG - "Firmware signature verification"
	o CONFIG_FIRMWARE_SIG_FORCE - "Require all firmware to be validly signed"

Everything about signing was done automatically behind the schemes for us, just
as with module signing.

If CONFIG_FIRMWARE_SIG_FORCE was *not* enabled, we'd grant unsigned firmwares
to be loaded, we'd just pr_warn() about them. Note that contrary to module
signing, firmware signing could not taint for technical reasons I listed on my
follow up patches after New Mexico Linux Plumbers [3]. Its worth re-iterating
so its not lost.

add_taint_module() is currently not exported, that can be fixed easily, but
also, the old firmware API currently does not associate the caller module in the
code, so we have a few options as to how to taint a kernel with unsigned firmware,
which I listed but I'll list here again:

  1) Extend the firmware_class driver API to require the correct module to
     always be set.

  2) Use add_taint_module() with the firmware_class module for the two
     synchrounous APIs, while using the right module for the async call.

  3) Use the firmware_class module for all 3 API calls when using
     add_taint_module()

  4) Skip tainting the kernel for unsigned firmware files

I went with 1) and 4) on that iteration of patches, with 1) only being done for
newer API calls. After this I stopped focusing on the firmware signing effort
as I first had to fix and clean up the firmware API in order to evolve it in a
more sane way for firmware signing later.

The "system policy" then was defined by kconfig. As per discussions it would
seem that some folks had issue with having a say the Linux Foundation being a
CA and say Kyle signing firmware would be kosher. In particular Alan Cox had
stated "A generic linux-firmware owned key would be both a horrendously
inviting attack target, and a single point of failure" [4].

Even if a default key is not used, old drivers may still desire to specify
a hash on an allowed firmware, and maybe that would suffice certain system
policies, however that is still a driver change, and an API call change, so
default policies for legacy drivers would still need to be considered when
evaluating and defining "system policies".

Andy has some work in progress worth evaluating for which could load a hash of
in-tree firmware into the kernel [5].

A system policy for "Kernel lockdown" may be compatible with the old approach
I had taken, its unclear and for that I'd ask David and others for feedback.

[0] https://lists.linuxfoundation.org/pipermail/ksummit-discuss/2015-July/001945.html
[1] https://lists.linuxfoundation.org/pipermail/ksummit-discuss/2015-July/001961.html
[2] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=fw-signing-v2-20150513
[3] https://lkml.kernel.org/r/1431541436-17007-1-git-send-email-mcgrof@do-not-panic.com
[4] https://lkml.kernel.org/r/20150526180813.0ba1b5f5@lxorguk.ukuu.org.uk
[5] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=intree_module_hashes

> If you allow me to bring in yet another function, say
> request_firmware_signable(), which should be used in place of (a)
> for all verification-aware drivers, that would be fine.

Right, so you're suggesting that if we instead had firmware singing
implemented as a new call, that supporting different policies would be
not just much easier, but possible.

I see your point and indeed its unclear to me at this time how to make
verify_firmware() work for legacy drivers with a system policy that is
a strict "kernel lockdown" policy which rejects unsigned firmware.

The obvious alternative, which I had suggested in my first iteration of patches
was to do the signature check for every call underneath the hood for *all*
callers depending on a Kconfig symbols, just as we deal with module signing,
but that has the limitations listed above about taint and also requiring
a default key for legacy drivers. Even though some folks may have issues with
a default firmware key, it could solve that.

That would load foo.bin. and its signature file, say foo.bin.p7s or
foo.bin.sign, or whatever. So it could check a signature if one is required
(say kernel lock down system policy) and just fail.

> In this case, all the invocation of request_firmware() in legacy code
> could be forced to fail in locked-down kernel.

That's also another option and its worth to hash out.

Since we got into this because I noted I have given into the functional API
design approach I think its worth it to say a bit more about that in comparison
to the data driven API I had proposed a while ago and also a bit about LSMs.

If it can work (its unclear it seems yet), in *this** particular case I think
it can make some sense to ask of something like a new verify_firmware() call
for this feature, given it may imply to do a good amount of work, in this case
fetch a signature file and verify it.

It'd be kind of silly to add tons of _signable() variations, so provided we're
OK in a verify_firmware() call to load the signature *after*, I see no issue
here.

That said, long term the functional API approach still may require adding
variations for other minor features but which require less amount of work
and for which I think then I think its reasonable to say that a "radical
functional API" approach just makes no sense.

For example, today we have request_firmware() for sync and
request_firmware_direct() when we wish to make it explicit sync request is
optional. But we have no equivalent optional semantics for async calls, we may
need this in the future, and sprinkling a postfix just for that seems rather
silly to me, specially when the only difference is just a simple flag check. By
contrast a verify_firmware() call can do much more work, and as such it seems
fair to argue for it.

The reason I had given up with the data driven API was that it was also radical,
I had suggested only two API calls, a sync and an async call, and left one huge
data structure to enable to modify behaviour in any possible way. This is just
as radical.

Mandating a new API call per *any* new feature is just stupid as requiring a
full blown data structure for any conceivable feature for an API.

So a "radical functional API" design approach is just as crazy as a
   a "radical data driven API" design approach.

A middle ground is sensible.

The optional mechanism is one which clearly should just be a flag, and so
I'll be first fixing the firmware API flag mess.

Firmware signing however requires a different possible set of requirements so
depending on what is agreed upon for a default system policy for legacy drivers,
it may or may not make sense for a new separate API call.

Lastly, long ago it was discussed that how the Linux kernel does module
signing really should be an LSM, but back in the day we didn't have stackable
LSMs, so this was not possible. Since we do now support stackable LSMs,
moving module signing to an LSM is in theory possible, and how we handle
firmware signing could also be an LSM. This way the approach you take to
firmware signing is more tied down to a form of security system policy
rather than some random kernel config option.

> But I think that "signable" should be allowed to be combined with other
> features of request_firmware variants like _(no)wait or _direct.

Let's first hash out the default policy allowed and how it can work with verify_firmware()
or if we need to abandon that idea.

  Luis

  parent reply index

Thread overview: 151+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-19 14:50 David Howells
2017-10-19 14:50 ` [PATCH 01/27] Add the ability to lock down access to the running kernel image David Howells
2017-10-20 23:19   ` James Morris
2017-10-19 14:50 ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown David Howells
2017-10-19 17:20   ` Randy Dunlap
2017-10-19 22:12   ` David Howells
2017-11-07 17:39   ` Thiago Jung Bauermann
2017-11-07 22:56   ` David Howells
2017-10-19 14:50 ` [PATCH 03/27] Enforce module signatures if the kernel is locked down David Howells
2017-10-20  6:33   ` joeyli
2017-10-20 23:21   ` James Morris
2017-10-27 18:48   ` Mimi Zohar
2017-10-30 17:00   ` David Howells
2017-10-30 17:52     ` Mimi Zohar
2017-11-02 17:22   ` David Howells
2017-11-02 19:13     ` Mimi Zohar
2017-11-02 21:30     ` David Howells
2017-11-02 21:41       ` Mimi Zohar
2017-11-02 22:01       ` David Howells
2017-11-02 22:18         ` Mimi Zohar
2017-10-19 14:51 ` [PATCH 04/27] Restrict /dev/mem and /dev/kmem when " David Howells
2017-10-20  6:37   ` joeyli
2017-10-20 23:21   ` James Morris
2017-10-19 14:51 ` [PATCH 05/27] kexec: Disable at runtime if " David Howells
2017-10-20  6:38   ` joeyli
2017-10-20 23:22   ` James Morris
2017-10-19 14:51 ` [PATCH 06/27] Copy secure_boot flag in boot params across kexec reboot David Howells
2017-10-20  6:40   ` joeyli
2017-10-19 14:51 ` [PATCH 07/27] kexec_file: Disable at runtime if securelevel has been set David Howells
2017-10-20 23:26   ` James Morris
2017-10-23 15:54   ` Mimi Zohar
2017-10-26  7:42     ` joeyli
2017-10-26 14:17       ` Mimi Zohar
2017-10-27 19:30         ` Mimi Zohar
2017-10-27 19:32         ` Mimi Zohar
2017-10-28  8:34           ` joeyli
2017-10-29 22:26             ` Mimi Zohar
2017-10-30  9:00       ` David Howells
2017-10-30 12:01         ` Mimi Zohar
2017-10-26 15:02     ` David Howells
2017-10-26 15:46       ` Mimi Zohar
2017-10-30 15:49       ` David Howells
2017-10-30 16:43         ` Mimi Zohar
2017-11-02 17:00         ` David Howells
2017-10-26 14:51   ` David Howells
2017-11-02 17:29   ` David Howells
2017-10-19 14:51 ` [PATCH 08/27] hibernate: Disable when the kernel is locked down David Howells
2017-10-20  6:40   ` joeyli
2017-10-19 14:51 ` [PATCH 09/27] uswsusp: " David Howells
2017-10-20  6:41   ` joeyli
2017-10-20 23:29   ` James Morris
2017-10-19 14:51 ` [PATCH 10/27] PCI: Lock down BAR access " David Howells
2017-10-20  6:42   ` joeyli
2017-10-19 14:51 ` [PATCH 11/27] x86: Lock down IO port " David Howells
2017-10-20  6:43   ` joeyli
2017-10-19 14:52 ` [PATCH 12/27] x86/msr: Restrict MSR " David Howells
2017-10-20  6:43   ` joeyli
2017-10-20 18:09   ` Alan Cox
2017-10-20 20:48   ` David Howells
2017-10-21  4:39     ` joeyli
2017-10-23 14:49   ` David Howells
2017-10-25 14:03     ` joeyli
2017-10-19 14:52 ` [PATCH 13/27] asus-wmi: Restrict debugfs interface " David Howells
2017-10-20  6:44   ` joeyli
2017-10-19 14:52 ` [PATCH 14/27] ACPI: Limit access to custom_method " David Howells
2017-10-20  6:45   ` joeyli
2017-10-19 14:52 ` [PATCH 15/27] acpi: Ignore acpi_rsdp kernel param when the kernel has been " David Howells
2017-10-20  6:45   ` joeyli
2017-10-19 14:52 ` [PATCH 16/27] acpi: Disable ACPI table override if the kernel is " David Howells
2017-10-20  6:46   ` joeyli
2017-10-19 14:52 ` [PATCH 17/27] acpi: Disable APEI error injection " David Howells
2017-10-20  6:47   ` joeyli
2017-10-19 14:52 ` [PATCH 18/27] bpf: Restrict kernel image access functions when " David Howells
2017-10-19 22:18   ` Alexei Starovoitov
2017-10-20  2:47     ` joeyli
2017-10-20  8:08     ` David Howells
2017-10-20 15:57       ` jlee
2017-10-20 23:00         ` Alexei Starovoitov
2017-10-23 14:51         ` David Howells
2017-10-20 16:03       ` David Howells
2017-10-20 16:43         ` jlee
2017-10-23 14:53         ` David Howells
2017-10-25  7:07           ` joeyli
2017-10-19 22:48   ` David Howells
2017-10-19 23:31     ` Alexei Starovoitov
2017-11-09 17:15     ` David Howells
2017-10-19 14:52 ` [PATCH 19/27] scsi: Lock down the eata driver David Howells
2017-10-19 14:53 ` [PATCH 20/27] Prohibit PCMCIA CIS storage when the kernel is locked down David Howells
2017-10-19 14:53 ` [PATCH 21/27] Lock down TIOCSSERIAL David Howells
2017-10-19 14:53 ` [PATCH 22/27] Lock down module params that specify hardware parameters (eg. ioport) David Howells
2017-10-19 14:53 ` [PATCH 23/27] x86/mmiotrace: Lock down the testmmiotrace module David Howells
2017-10-19 14:53 ` [PATCH 24/27] debugfs: Disallow use of debugfs files when the kernel is locked down David Howells
2017-10-19 14:53 ` [PATCH 25/27] Lock down /proc/kcore David Howells
2017-10-21  2:11   ` James Morris
2017-10-23 14:56   ` David Howells
2017-10-19 14:53 ` [PATCH 26/27] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode David Howells
2017-10-21  2:19   ` James Morris
2017-10-23 14:58   ` David Howells
2017-10-19 14:53 ` [PATCH 27/27] efi: Lock down the kernel if booted in " David Howells
2017-10-19 22:39 ` [PATCH 00/27] security, efi: Add kernel lockdown David Howells
2017-10-23 14:34 ` [PATCH 04/27] Restrict /dev/mem and /dev/kmem when the kernel is locked down David Howells
2017-10-24 10:48   ` Ethan Zhao
2017-10-24 14:56   ` David Howells
2017-11-02 22:01 ` [PATCH 00/27] security, efi: Add kernel lockdown Mimi Zohar
2017-11-02 22:04 ` Firmware signing -- " David Howells
2017-11-02 22:10   ` Mimi Zohar
2017-11-07 23:07     ` Luis R. Rodriguez
2017-11-08  6:15       ` AKASHI, Takahiro
2017-11-08 19:46         ` Luis R. Rodriguez
2017-11-09  1:48           ` AKASHI, Takahiro
2017-11-09  2:17             ` Mimi Zohar
2017-11-09  4:46               ` AKASHI, Takahiro
2017-11-10 13:37                 ` Mimi Zohar
2017-11-11  2:32                 ` Alan Cox
2017-11-13 11:49                   ` Mimi Zohar
2017-11-13 17:42                   ` Luis R. Rodriguez
2017-11-13 21:08                     ` Alan Cox
2017-12-04 19:51                       ` Luis R. Rodriguez
2017-12-07 15:32                         ` Alan Cox
2017-11-13 21:44                     ` David Howells
2017-11-13 22:09                       ` Linus Torvalds
2017-11-14  0:20                         ` Alan Cox
2017-11-14 12:21                         ` Mimi Zohar
2017-11-14 12:38                           ` Greg Kroah-Hartman
2017-11-14 13:17                             ` Mimi Zohar
2017-11-14 17:34                           ` Linus Torvalds
2017-11-14 19:58                             ` Matthew Garrett
2017-11-14 20:18                               ` Linus Torvalds
2017-11-14 20:31                                 ` Matthew Garrett
2017-11-14 20:35                                   ` Linus Torvalds
2017-11-14 20:37                                     ` Matthew Garrett
2017-11-14 20:50                                 ` Luis R. Rodriguez
2017-11-14 20:55                                   ` Matthew Garrett
2017-11-14 22:14                                     ` James Bottomley
2017-11-14 22:17                                       ` Matthew Garrett
2017-11-14 22:31                                         ` James Bottomley
2017-11-14 22:34                                           ` Matthew Garrett
2017-11-15 11:49                                   ` Mimi Zohar
2017-11-15 17:52                                     ` Luis R. Rodriguez
2017-11-15 19:56                                       ` Mimi Zohar
2017-11-15 20:46                                         ` Luis R. Rodriguez
2017-11-16  0:05                                           ` Mimi Zohar
2017-12-05 10:27                                 ` Pavel Machek
2017-12-07 23:02                                   ` Luis R. Rodriguez
2017-12-08 17:11                                     ` Alan Cox
2017-11-10  1:46             ` Luis R. Rodriguez [this message]
2017-11-10 13:45               ` Mimi Zohar
2017-11-13 18:50                 ` Luis R. Rodriguez
2017-11-13 19:08                   ` Luis R. Rodriguez
2017-11-08 20:01       ` Mimi Zohar
2017-11-08 20:09         ` Luis R. Rodriguez

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=20171110014641.GO22894@wotan.suse.de \
    --to=mcgrof@kernel.org \
    --cc=GLin@suse.com \
    --cc=James.Bottomley@hansenpartnership.com \
    --cc=dhowells@redhat.com \
    --cc=dwmw2@infradead.org \
    --cc=gnomes@lxorguk.ukuu.org.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=jblunck@infradead.org \
    --cc=josh@joshtriplett.org \
    --cc=julia.lawall@lip6.fr \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=meissner@suse.de \
    --cc=mjg59@google.com \
    --cc=pjones@redhat.com \
    --cc=takahiro.akashi@linaro.org \
    --cc=torvalds@linux-foundation.org \
    --cc=zohar@linux.vnet.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

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git