This third patch series includes back three fix patches taken from the first
series (and cherry-picked from David Howells's tree [1]), and one cosmetic fix
from Alex Shi which helps avoid future conflicts. I also added some Acked-by
and improved comments. As requested, this series is based on v5.11-rc3.
The goal of these patches is to add a new configuration option to enable the
root user to load signed keys in the blacklist keyring. This keyring is useful
to "untrust" certificates or files. Enabling to safely update this keyring
without recompiling the kernel makes it more usable.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-fixes
Previous patch series:
https://lore.kernel.org/lkml/20201211190330.2586116-1-mic@digikod.net/
Regards,
Alex Shi (1):
certs/blacklist: fix kernel doc interface issue
David Howells (1):
certs: Fix blacklist flag type confusion
Mickaël Salaün (8):
certs: Fix blacklisted hexadecimal hash string check
PKCS#7: Fix missing include
certs: Replace K{U,G}IDT_INIT() with GLOBAL_ROOT_{U,G}ID
certs: Make blacklist_vet_description() more strict
certs: Factor out the blacklist hash creation
certs: Check that builtin blacklist hashes are valid
certs: Allow root user to append signed hashes to the blacklist
keyring
tools/certs: Add print-cert-tbs-hash.sh
MAINTAINERS | 2 +
certs/.gitignore | 1 +
certs/Kconfig | 10 +
certs/Makefile | 15 +-
certs/blacklist.c | 217 ++++++++++++++----
certs/system_keyring.c | 5 +-
crypto/asymmetric_keys/x509_public_key.c | 3 +-
include/keys/system_keyring.h | 14 +-
include/linux/key.h | 1 +
include/linux/verification.h | 2 +
scripts/check-blacklist-hashes.awk | 37 +++
security/integrity/ima/ima_mok.c | 4 +-
.../platform_certs/keyring_handler.c | 26 +--
security/keys/key.c | 2 +
tools/certs/print-cert-tbs-hash.sh | 91 ++++++++
15 files changed, 345 insertions(+), 85 deletions(-)
create mode 100755 scripts/check-blacklist-hashes.awk
create mode 100755 tools/certs/print-cert-tbs-hash.sh
base-commit: 7c53f6b671f4aba70ff15e1b05148b10d58c2837
--
2.30.0
From: David Howells <dhowells@redhat.com>
KEY_FLAG_KEEP is not meant to be passed to keyring_alloc() or key_alloc(),
as these only take KEY_ALLOC_* flags. KEY_FLAG_KEEP has the same value as
KEY_ALLOC_BYPASS_RESTRICTION, but fortunately only key_create_or_update()
uses it. LSMs using the key_alloc hook don't check that flag.
KEY_FLAG_KEEP is then ignored but fortunately (again) the root user cannot
write to the blacklist keyring, so it is not possible to remove a key/hash
from it.
Fix this by adding a KEY_ALLOC_SET_KEEP flag that tells key_alloc() to set
KEY_FLAG_KEEP on the new key. blacklist_init() can then, correctly, pass
this to keyring_alloc().
We can also use this in ima_mok_init() rather than setting the flag
manually.
Note that this doesn't fix an observable bug with the current
implementation but it is required to allow addition of new hashes to the
blacklist in the future without making it possible for them to be removed.
Fixes: 734114f8782f ("KEYS: Add a system blacklist keyring")
cc: Mimi Zohar <redacted>
Cc: David Woodhouse <dwmw2@infradead.org>
Reported-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
[mic@linux.microsoft.com: fix ima_mok_init()]
Signed-off-by: Mickaël Salaün <redacted>
---
Changes since v2:
* Cherry-pick rewritten v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3 and fix ima_mok_init().
---
certs/blacklist.c | 2 +-
include/linux/key.h | 1 +
security/integrity/ima/ima_mok.c | 4 +---
security/keys/key.c | 2 ++
4 files changed, 5 insertions(+), 4 deletions(-)
@@ -289,6 +289,7 @@ extern struct key *key_alloc(struct key_type *type,#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */+#define KEY_ALLOC_SET_KEEP 0x0020 /* Set the KEEP flag on the key/keyring */externvoidkey_revoke(structkey*key);externvoidkey_invalidate(structkey*key);
From: Mickaël Salaün <redacted>
Factor out the blacklist hash creation with the get_raw_hash() helper.
This also centralize the "tbs" and "bin" prefixes and make them private,
which help to manage them consistently.
Cc: David Howells <dhowells@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
---
Changes since v2:
* Add Jarkko's Acked-by.
---
certs/blacklist.c | 73 ++++++++++++++-----
crypto/asymmetric_keys/x509_public_key.c | 3 +-
include/keys/system_keyring.h | 14 +++-
.../platform_certs/keyring_handler.c | 26 +------
4 files changed, 70 insertions(+), 46 deletions(-)
From: Mickaël Salaün <redacted>
Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes will be approved by the run time blacklist
description checks. This is useful to debug invalid hash formats, and
it make sure that previous hashes which could have been loaded in the
kernel (but ignored) are now noticed and deal with by the user.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
---
Changes since v2:
* Add Jarkko's Acked-by.
Changes since v1:
* Prefix script path with $(scrtree)/ (suggested by David Howells).
* Fix hexadecimal number check.
---
MAINTAINERS | 1 +
certs/.gitignore | 1 +
certs/Makefile | 15 +++++++++++-
scripts/check-blacklist-hashes.awk | 37 ++++++++++++++++++++++++++++++
4 files changed, 53 insertions(+), 1 deletion(-)
create mode 100755 scripts/check-blacklist-hashes.awk
From: Mickaël Salaün <redacted>
Before exposing this new key type to user space, make sure that only
meaningful blacklisted hashes are accepted. This is also checked for
builtin blacklisted hashes, but a following commit make sure that the
user will notice (at built time) and will fix the configuration if it
already included errors.
Check that a blacklist key description starts with a valid prefix and
then a valid hexadecimal string.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
---
Changes since v2:
* Fix typo in blacklist_vet_description() comment, spotted by Tyler
Hicks.
* Add Jarkko's Acked-by.
Changes since v1:
* Return ENOPKG (instead of EINVAL) when a hash is greater than the
maximum currently known hash (suggested by David Howells).
---
certs/blacklist.c | 46 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 36 insertions(+), 10 deletions(-)
@@ -26,24 +36,40 @@ static struct key *blacklist_keyring;*/staticintblacklist_vet_description(constchar*desc){-intn=0;--if(*desc==':')-return-EINVAL;-for(;*desc;desc++)-if(*desc==':')-gotofound_colon;+inti,prefix_len,tbs_step=0,bin_step=0;++/* The following algorithm only works if prefix lengths match. */+BUILD_BUG_ON(sizeof(tbs_prefix)!=sizeof(bin_prefix));+prefix_len=sizeof(tbs_prefix)-1;+for(i=0;*desc;desc++,i++){+if(*desc==':'){+if(tbs_step==prefix_len)+gotofound_colon;+if(bin_step==prefix_len)+gotofound_colon;+return-EINVAL;+}+if(i>=prefix_len)+return-EINVAL;+if(*desc==tbs_prefix[i])+tbs_step++;+if(*desc==bin_prefix[i])+bin_step++;+}return-EINVAL;found_colon:desc++;-for(;*desc;desc++){+for(i=0;*desc&&i<MAX_HASH_LEN;desc++,i++){if(!isxdigit(*desc)||isupper(*desc))return-EINVAL;-n++;}+if(*desc)+/* The hash is greater than MAX_HASH_LEN. */+return-ENOPKG;-if(n==0||n&1)+/* Checks for an even number of hexadecimal characters. */+if(i==0||i&1)return-EINVAL;return0;}
From: Alex Shi <redacted>
certs/blacklist.c:84: warning: Function parameter or member 'hash' not
described in 'mark_hash_blacklisted'
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: keyrings@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Alex Shi <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <redacted>
Signed-off-by: Mickaël Salaün <redacted>
---
Changes since v2:
* Cherry-pick patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to avoid future merge conflicts.
* Rearrange Signed-off-by and Reviewed-by order.
---
certs/blacklist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Mickaël Salaün <redacted>
Align with the new macros and add appropriate include files.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
---
Changes since v2:
* Cherry-pick v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3.
---
certs/blacklist.c | 4 ++--
certs/system_keyring.c | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
From: Mickaël Salaün <redacted>
Add a kernel option SYSTEM_BLACKLIST_AUTH_UPDATE to enable the root user
to dynamically add new keys to the blacklist keyring. This enables to
invalidate new certificates, either from being loaded in a keyring, or
from being trusted in a PKCS#7 certificate chain. This also enables to
add new file hashes to be denied by the integrity infrastructure.
Being able to untrust a certificate which could have normaly been
trusted is a sensitive operation. This is why adding new hashes to the
blacklist keyring is only allowed when these hashes are signed and
vouched by the builtin trusted keyring. A blacklist hash is stored as a
key description. The PKCS#7 signature of this description must be
provided as the key payload.
Marking a certificate as untrusted should be enforced while the system
is running. It is then forbiden to remove such blacklist keys.
Update blacklist keyring and blacklist key access rights:
* allows the root user to search for a specific blacklisted hash, which
make sense because the descriptions are already viewable;
* forbids key update;
* restricts kernel rights on the blacklist keyring to align with the
root user rights.
See the help in tools/certs/print-cert-tbs-hash.sh provided by a
following commit.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
---
Changes since v2:
* Add comment for blacklist_key_instantiate().
---
certs/Kconfig | 10 ++++++
certs/blacklist.c | 90 +++++++++++++++++++++++++++++++++++++----------
2 files changed, 81 insertions(+), 19 deletions(-)
From: Mickaël Salaün <redacted>
Add a new helper print-cert-tbs-hash.sh to generate a TBSCertificate
hash from a given certificate. This is useful to generate a blacklist
key description used to forbid loading a specific certificate in a
keyring, or to invalidate a certificate provided by a PKCS#7 file.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
---
Changes since v1:
* Fix typo.
* Use "if" block instead of "||" .
---
MAINTAINERS | 1 +
tools/certs/print-cert-tbs-hash.sh | 91 ++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
create mode 100755 tools/certs/print-cert-tbs-hash.sh
From: Mickaël Salaün <redacted>
When looking for a blacklisted hash, bin2hex() is used to transform a
binary hash to an ascii (lowercase) hexadecimal string. This string is
then search for in the description of the keys from the blacklist
keyring. When adding a key to the blacklist keyring,
blacklist_vet_description() checks the hash prefix and the hexadecimal
string, but not that this string is lowercase. It is then valid to set
hashes with uppercase hexadecimal, which will be silently ignored by the
kernel.
Add an additional check to blacklist_vet_description() to check that
hexadecimal strings are in lowercase.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <redacted>
---
Changes since v2:
* Cherry-pick v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3.
* Rearrange Cc order.
---
certs/blacklist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-15 09:29:48
On Thu, Jan 14, 2021 at 04:18:59PM +0100, Mickaël Salaün wrote:
This third patch series includes back three fix patches taken from the first
series (and cherry-picked from David Howells's tree [1]), and one cosmetic fix
from Alex Shi which helps avoid future conflicts. I also added some Acked-by
and improved comments. As requested, this series is based on v5.11-rc3.
The goal of these patches is to add a new configuration option to enable the
root user to load signed keys in the blacklist keyring. This keyring is useful
to "untrust" certificates or files. Enabling to safely update this keyring
without recompiling the kernel makes it more usable.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-fixes
Previous patch series:
https://lore.kernel.org/lkml/20201211190330.2586116-1-mic@digikod.net/
Regards,
Alex Shi (1):
certs/blacklist: fix kernel doc interface issue
David Howells (1):
certs: Fix blacklist flag type confusion
Mickaël Salaün (8):
certs: Fix blacklisted hexadecimal hash string check
PKCS#7: Fix missing include
certs: Replace K{U,G}IDT_INIT() with GLOBAL_ROOT_{U,G}ID
certs: Make blacklist_vet_description() more strict
certs: Factor out the blacklist hash creation
certs: Check that builtin blacklist hashes are valid
certs: Allow root user to append signed hashes to the blacklist
keyring
tools/certs: Add print-cert-tbs-hash.sh
MAINTAINERS | 2 +
certs/.gitignore | 1 +
certs/Kconfig | 10 +
certs/Makefile | 15 +-
certs/blacklist.c | 217 ++++++++++++++----
certs/system_keyring.c | 5 +-
crypto/asymmetric_keys/x509_public_key.c | 3 +-
include/keys/system_keyring.h | 14 +-
include/linux/key.h | 1 +
include/linux/verification.h | 2 +
scripts/check-blacklist-hashes.awk | 37 +++
security/integrity/ima/ima_mok.c | 4 +-
.../platform_certs/keyring_handler.c | 26 +--
security/keys/key.c | 2 +
tools/certs/print-cert-tbs-hash.sh | 91 ++++++++
15 files changed, 345 insertions(+), 85 deletions(-)
create mode 100755 scripts/check-blacklist-hashes.awk
create mode 100755 tools/certs/print-cert-tbs-hash.sh
base-commit: 7c53f6b671f4aba70ff15e1b05148b10d58c2837
--
2.30.0
Thank you. Unfortunately no time to review this anymore this week but I
sanity checked that this applies cleanly now, so should be easy to get on
testing this series next week:
$ git-pw series apply 414691
Applying: certs/blacklist: fix kernel doc interface issue
Applying: certs: Fix blacklisted hexadecimal hash string check
Applying: PKCS#7: Fix missing include
Applying: certs: Fix blacklist flag type confusion
Applying: certs: Replace K{U,G}IDT_INIT() with GLOBAL_ROOT_{U,G}ID
Applying: certs: Make blacklist_vet_description() more strict
Applying: certs: Factor out the blacklist hash creation
Applying: certs: Check that builtin blacklist hashes are valid
Applying: certs: Allow root user to append signed hashes to the blacklist keyring
Applying: tools/certs: Add print-cert-tbs-hash.sh
/Jarkko
Hi Mickaël,
On Thu, 2021-01-14 at 16:19 +0100, Mickaël Salaün wrote:
From: Mickaël Salaün <redacted>
Add a kernel option SYSTEM_BLACKLIST_AUTH_UPDATE to enable the root user
to dynamically add new keys to the blacklist keyring. This enables to
invalidate new certificates, either from being loaded in a keyring, or
from being trusted in a PKCS#7 certificate chain. This also enables to
add new file hashes to be denied by the integrity infrastructure.
Being able to untrust a certificate which could have normaly been
trusted is a sensitive operation. This is why adding new hashes to the
blacklist keyring is only allowed when these hashes are signed and
vouched by the builtin trusted keyring. A blacklist hash is stored as a
key description. The PKCS#7 signature of this description must be
provided as the key payload.
Marking a certificate as untrusted should be enforced while the system
is running. It is then forbiden to remove such blacklist keys.
Update blacklist keyring and blacklist key access rights:
* allows the root user to search for a specific blacklisted hash, which
make sense because the descriptions are already viewable;
* forbids key update;
* restricts kernel rights on the blacklist keyring to align with the
root user rights.
See the help in tools/certs/print-cert-tbs-hash.sh provided by a
following commit.
The design looks good. I'm hoping to review/test at least this patch
next week.
thanks,
Mimi
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 03:42:27
On Thu, Jan 14, 2021 at 04:19:00PM +0100, Mickaël Salaün wrote:
From: Alex Shi <redacted>
certs/blacklist.c:84: warning: Function parameter or member 'hash' not
described in 'mark_hash_blacklisted'
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: keyrings@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Alex Shi <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <redacted>
Signed-off-by: Mickaël Salaün <redacted>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
/Jarkko
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 03:48:39
On Thu, Jan 14, 2021 at 04:19:01PM +0100, Mickaël Salaün wrote:
quoted hunk
From: Mickaël Salaün <redacted>
When looking for a blacklisted hash, bin2hex() is used to transform a
binary hash to an ascii (lowercase) hexadecimal string. This string is
then search for in the description of the keys from the blacklist
keyring. When adding a key to the blacklist keyring,
blacklist_vet_description() checks the hash prefix and the hexadecimal
string, but not that this string is lowercase. It is then valid to set
hashes with uppercase hexadecimal, which will be silently ignored by the
kernel.
Add an additional check to blacklist_vet_description() to check that
hexadecimal strings are in lowercase.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <redacted>
---
Changes since v2:
* Cherry-pick v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3.
* Rearrange Cc order.
---
certs/blacklist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 03:58:52
On Thu, Jan 14, 2021 at 04:19:03PM +0100, Mickaël Salaün wrote:
From: David Howells <dhowells@redhat.com>
KEY_FLAG_KEEP is not meant to be passed to keyring_alloc() or key_alloc(),
as these only take KEY_ALLOC_* flags. KEY_FLAG_KEEP has the same value as
KEY_ALLOC_BYPASS_RESTRICTION, but fortunately only key_create_or_update()
uses it. LSMs using the key_alloc hook don't check that flag.
KEY_FLAG_KEEP is then ignored but fortunately (again) the root user cannot
write to the blacklist keyring, so it is not possible to remove a key/hash
from it.
Fix this by adding a KEY_ALLOC_SET_KEEP flag that tells key_alloc() to set
KEY_FLAG_KEEP on the new key. blacklist_init() can then, correctly, pass
this to keyring_alloc().
OK, so thing work by luck now, but given the new patches which allow
to append new keys they would break, right?
We can also use this in ima_mok_init() rather than setting the flag
manually.
What does ima_mok_init() do?
Note that this doesn't fix an observable bug with the current
implementation but it is required to allow addition of new hashes to the
blacklist in the future without making it possible for them to be removed.
Fixes: 734114f8782f ("KEYS: Add a system blacklist keyring")
cc: Mimi Zohar <redacted>
Nit: Cc
quoted hunk
Cc: David Woodhouse <dwmw2@infradead.org>
Reported-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
[mic@linux.microsoft.com: fix ima_mok_init()]
Signed-off-by: Mickaël Salaün <redacted>
---
Changes since v2:
* Cherry-pick rewritten v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3 and fix ima_mok_init().
---
certs/blacklist.c | 2 +-
include/linux/key.h | 1 +
security/integrity/ima/ima_mok.c | 4 +---
security/keys/key.c | 2 ++
4 files changed, 5 insertions(+), 4 deletions(-)
@@ -289,6 +289,7 @@ extern struct key *key_alloc(struct key_type *type,#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */+#define KEY_ALLOC_SET_KEEP 0x0020 /* Set the KEEP flag on the key/keyring */externvoidkey_revoke(structkey*key);externvoidkey_invalidate(structkey*key);
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 04:22:23
On Thu, Jan 14, 2021 at 04:19:05PM +0100, Mickaël Salaün wrote:
From: Mickaël Salaün <redacted>
Before exposing this new key type to user space, make sure that only
meaningful blacklisted hashes are accepted. This is also checked for
builtin blacklisted hashes, but a following commit make sure that the
user will notice (at built time) and will fix the configuration if it
already included errors.
Check that a blacklist key description starts with a valid prefix and
then a valid hexadecimal string.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
In this I'm not as worried about ABI, i.e. you don't have any reason
supply any other data, which doesn't follow these ruels, whereas there
could very well be a script that does format hex "incorrectly".
/Jarkko
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 05:27:26
On Thu, Jan 14, 2021 at 04:19:04PM +0100, Mickaël Salaün wrote:
From: Mickaël Salaün <redacted>
Align with the new macros and add appropriate include files.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
The commit message makes no sense. What you new macros?
/Jarkko
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 05:30:33
On Thu, Jan 14, 2021 at 04:19:07PM +0100, Mickaël Salaün wrote:
From: Mickaël Salaün <redacted>
Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes will be approved by the run time blacklist
description checks. This is useful to debug invalid hash formats, and
it make sure that previous hashes which could have been loaded in the
kernel (but ignored) are now noticed and deal with by the user.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
I get this with a self-signed cert:
certs/Makefile:18: *** target pattern contains no '%'. Stop.
CONFIG_SYSTEM_BLACKLIST_HASH_LIST="tbs:8eed1340eef37c1dc84d996406ad05c7dbb3eade19132d688408ca2f63904869"
I used the script in 10/10 to test this, which is another
reamark: the patches are in invalid order, as you need to
apply 10/10 before you can test 8/10.
/Jarkko
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-20 05:30:33
On Thu, Jan 14, 2021 at 04:19:08PM +0100, Mickaël Salaün wrote:
From: Mickaël Salaün <redacted>
Add a kernel option SYSTEM_BLACKLIST_AUTH_UPDATE to enable the root user
to dynamically add new keys to the blacklist keyring. This enables to
invalidate new certificates, either from being loaded in a keyring, or
from being trusted in a PKCS#7 certificate chain. This also enables to
add new file hashes to be denied by the integrity infrastructure.
Being able to untrust a certificate which could have normaly been
trusted is a sensitive operation. This is why adding new hashes to the
blacklist keyring is only allowed when these hashes are signed and
vouched by the builtin trusted keyring. A blacklist hash is stored as a
key description. The PKCS#7 signature of this description must be
provided as the key payload.
Marking a certificate as untrusted should be enforced while the system
is running. It is then forbiden to remove such blacklist keys.
Update blacklist keyring and blacklist key access rights:
* allows the root user to search for a specific blacklisted hash, which
make sense because the descriptions are already viewable;
* forbids key update;
* restricts kernel rights on the blacklist keyring to align with the
root user rights.
See the help in tools/certs/print-cert-tbs-hash.sh provided by a
following commit.
Please re-order patches in a way that print-cert-tbs-hash.sh is
available before this. That way we get rid of this useless remark.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
On Thu, Jan 14, 2021 at 04:19:01PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
When looking for a blacklisted hash, bin2hex() is used to transform a
binary hash to an ascii (lowercase) hexadecimal string. This string is
then search for in the description of the keys from the blacklist
keyring. When adding a key to the blacklist keyring,
blacklist_vet_description() checks the hash prefix and the hexadecimal
string, but not that this string is lowercase. It is then valid to set
hashes with uppercase hexadecimal, which will be silently ignored by the
kernel.
Add an additional check to blacklist_vet_description() to check that
hexadecimal strings are in lowercase.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <redacted>
---
Changes since v2:
* Cherry-pick v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3.
* Rearrange Cc order.
---
certs/blacklist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -37,7 +37,7 @@ static int blacklist_vet_description(const char *desc)found_colon:desc++;for(;*desc;desc++){-if(!isxdigit(*desc))+if(!isxdigit(*desc)||isupper(*desc))return-EINVAL;n++;}
--
2.30.0
Shouldn't this rather convert the upper case to lower case? I don't like
the ABI break that this causes.
It doesn't break the ABI because keys loaded in the blacklist keyring
can only happen with builtin hashes. Moreover these builtin hashes will
be checked by patch 10/10 at build time.
This patch is also important to remove a false sense of security and
warns about mis-blacklisted certificates or binaries:
https://lore.kernel.org/lkml/c9664a67-61b7-6b4a-86d7-5aca9ff06fa5@digikod.net/
Hot-patching keys doesn't seem a good idea, especially when these keys
are signed. Moreover, it would bring additional complexity and will
require to change the core of the key management.
On Thu, Jan 14, 2021 at 04:19:04PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Align with the new macros and add appropriate include files.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
The commit message makes no sense. What you new macros?
What about "Use the new GLOBAL_ROOT_UID and GLOBAL_ROOT_GID definitions,
and add appropriate include files."?
On Thu, Jan 14, 2021 at 04:19:03PM +0100, Mickaël Salaün wrote:
quoted
From: David Howells <dhowells@redhat.com>
KEY_FLAG_KEEP is not meant to be passed to keyring_alloc() or key_alloc(),
as these only take KEY_ALLOC_* flags. KEY_FLAG_KEEP has the same value as
KEY_ALLOC_BYPASS_RESTRICTION, but fortunately only key_create_or_update()
uses it. LSMs using the key_alloc hook don't check that flag.
KEY_FLAG_KEEP is then ignored but fortunately (again) the root user cannot
write to the blacklist keyring, so it is not possible to remove a key/hash
from it.
Fix this by adding a KEY_ALLOC_SET_KEEP flag that tells key_alloc() to set
KEY_FLAG_KEEP on the new key. blacklist_init() can then, correctly, pass
this to keyring_alloc().
OK, so thing work by luck now, but given the new patches which allow
to append new keys they would break, right?
Without this fix, patch 9/10 would allow to remove and modify keys from
the blacklist keyring.
quoted
We can also use this in ima_mok_init() rather than setting the flag
manually.
What does ima_mok_init() do?
This was initially an addition from David Howells, I only fixed the
argument bit-ORing. ima_mok_init() allocates a blacklist keyring (with
different properties) dedicated to IMA.
quoted
Note that this doesn't fix an observable bug with the current
implementation but it is required to allow addition of new hashes to the
blacklist in the future without making it possible for them to be removed.
Fixes: 734114f8782f ("KEYS: Add a system blacklist keyring")
cc: Mimi Zohar <redacted>
Nit: Cc
OK
quoted
Cc: David Woodhouse <dwmw2@infradead.org>
Reported-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
[mic@linux.microsoft.com: fix ima_mok_init()]
Signed-off-by: Mickaël Salaün <redacted>
---
Changes since v2:
* Cherry-pick rewritten v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3 and fix ima_mok_init().
---
certs/blacklist.c | 2 +-
include/linux/key.h | 1 +
security/integrity/ima/ima_mok.c | 4 +---
security/keys/key.c | 2 ++
4 files changed, 5 insertions(+), 4 deletions(-)
@@ -289,6 +289,7 @@ extern struct key *key_alloc(struct key_type *type,#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */+#define KEY_ALLOC_SET_KEEP 0x0020 /* Set the KEEP flag on the key/keyring */externvoidkey_revoke(structkey*key);externvoidkey_invalidate(structkey*key);
On Thu, Jan 14, 2021 at 04:19:08PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Add a kernel option SYSTEM_BLACKLIST_AUTH_UPDATE to enable the root user
to dynamically add new keys to the blacklist keyring. This enables to
invalidate new certificates, either from being loaded in a keyring, or
from being trusted in a PKCS#7 certificate chain. This also enables to
add new file hashes to be denied by the integrity infrastructure.
Being able to untrust a certificate which could have normaly been
trusted is a sensitive operation. This is why adding new hashes to the
blacklist keyring is only allowed when these hashes are signed and
vouched by the builtin trusted keyring. A blacklist hash is stored as a
key description. The PKCS#7 signature of this description must be
provided as the key payload.
Marking a certificate as untrusted should be enforced while the system
is running. It is then forbiden to remove such blacklist keys.
Update blacklist keyring and blacklist key access rights:
* allows the root user to search for a specific blacklisted hash, which
make sense because the descriptions are already viewable;
* forbids key update;
* restricts kernel rights on the blacklist keyring to align with the
root user rights.
See the help in tools/certs/print-cert-tbs-hash.sh provided by a
following commit.
Please re-order patches in a way that print-cert-tbs-hash.sh is
available before this. That way we get rid of this useless remark.
OK
quoted
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
On Thu, Jan 14, 2021 at 04:19:05PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Before exposing this new key type to user space, make sure that only
meaningful blacklisted hashes are accepted. This is also checked for
builtin blacklisted hashes, but a following commit make sure that the
user will notice (at built time) and will fix the configuration if it
already included errors.
Check that a blacklist key description starts with a valid prefix and
then a valid hexadecimal string.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
In this I'm not as worried about ABI, i.e. you don't have any reason
supply any other data, which doesn't follow these ruels, whereas there
could very well be a script that does format hex "incorrectly".
I think I answered this comment in patch 2/10: there is no ABI breakage,
it only prepares for safe dynamic key addition. Patch 10/10 enables to
avoid using incorrect/useless/mis-leading hashes and force users to fix
these hashes (that were not taken into account)
On Thu, Jan 14, 2021 at 04:19:07PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes will be approved by the run time blacklist
description checks. This is useful to debug invalid hash formats, and
it make sure that previous hashes which could have been loaded in the
kernel (but ignored) are now noticed and deal with by the user.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
I get this with a self-signed cert:
certs/Makefile:18: *** target pattern contains no '%'. Stop.
CONFIG_SYSTEM_BLACKLIST_HASH_LIST="tbs:8eed1340eef37c1dc84d996406ad05c7dbb3eade19132d688408ca2f63904869"
As said in the Kconfig documentation for
CONFIG_SYSTEM_BLACKLIST_HASH_LIST, you need to provide a file with the
list, not to set the string directly in the configuration variable. This
patch series didn't change this behavior. The same kind of macros are
used for CONFIG_MODULE_SIG_KEY.
I used the script in 10/10 to test this, which is another
reamark: the patches are in invalid order, as you need to
apply 10/10 before you can test 8/10.
I'll move patch 10/10 earlier but this kind of formatting was already
required (but silently ignored) for this option to be really taken into
account. Only the kernel code was available to understand how to
effectively create such hash.
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-21 02:45:47
On Wed, Jan 20, 2021 at 12:17:28PM +0100, Mickaël Salaün wrote:
On 20/01/2021 06:15, Jarkko Sakkinen wrote:
quoted
On Thu, Jan 14, 2021 at 04:19:04PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Align with the new macros and add appropriate include files.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
The commit message makes no sense. What you new macros?
What about "Use the new GLOBAL_ROOT_UID and GLOBAL_ROOT_GID definitions,
and add appropriate include files."?
They were added in 2011 so you could just remove "the new". Otherwise,
WFM.
/Jarkko
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-21 02:45:47
On Wed, Jan 20, 2021 at 12:57:55PM +0100, Mickaël Salaün wrote:
On 20/01/2021 06:19, Jarkko Sakkinen wrote:
quoted
On Thu, Jan 14, 2021 at 04:19:07PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes will be approved by the run time blacklist
description checks. This is useful to debug invalid hash formats, and
it make sure that previous hashes which could have been loaded in the
kernel (but ignored) are now noticed and deal with by the user.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
I get this with a self-signed cert:
certs/Makefile:18: *** target pattern contains no '%'. Stop.
CONFIG_SYSTEM_BLACKLIST_HASH_LIST="tbs:8eed1340eef37c1dc84d996406ad05c7dbb3eade19132d688408ca2f63904869"
As said in the Kconfig documentation for
CONFIG_SYSTEM_BLACKLIST_HASH_LIST, you need to provide a file with the
list, not to set the string directly in the configuration variable. This
patch series didn't change this behavior. The same kind of macros are
used for CONFIG_MODULE_SIG_KEY.
OK, the documentation just states that:
"Hashes to be preloaded into the system blacklist keyring"
No mention about a file. I'd add a patch to update this documentation.
quoted
I used the script in 10/10 to test this, which is another
reamark: the patches are in invalid order, as you need to
apply 10/10 before you can test 8/10.
I'll move patch 10/10 earlier but this kind of formatting was already
required (but silently ignored) for this option to be really taken into
account. Only the kernel code was available to understand how to
effectively create such hash.
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-21 06:34:02
On Wed, Jan 20, 2021 at 12:15:10PM +0100, Mickaël Salaün wrote:
On 20/01/2021 04:55, Jarkko Sakkinen wrote:
quoted
On Thu, Jan 14, 2021 at 04:19:03PM +0100, Mickaël Salaün wrote:
quoted
From: David Howells <dhowells@redhat.com>
KEY_FLAG_KEEP is not meant to be passed to keyring_alloc() or key_alloc(),
as these only take KEY_ALLOC_* flags. KEY_FLAG_KEEP has the same value as
KEY_ALLOC_BYPASS_RESTRICTION, but fortunately only key_create_or_update()
uses it. LSMs using the key_alloc hook don't check that flag.
KEY_FLAG_KEEP is then ignored but fortunately (again) the root user cannot
write to the blacklist keyring, so it is not possible to remove a key/hash
from it.
Fix this by adding a KEY_ALLOC_SET_KEEP flag that tells key_alloc() to set
KEY_FLAG_KEEP on the new key. blacklist_init() can then, correctly, pass
this to keyring_alloc().
OK, so thing work by luck now, but given the new patches which allow
to append new keys they would break, right?
Without this fix, patch 9/10 would allow to remove and modify keys from
the blacklist keyring.
quoted
quoted
We can also use this in ima_mok_init() rather than setting the flag
manually.
What does ima_mok_init() do?
This was initially an addition from David Howells, I only fixed the
argument bit-ORing. ima_mok_init() allocates a blacklist keyring (with
different properties) dedicated to IMA.
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-21 06:39:48
On Wed, Jan 20, 2021 at 12:12:50PM +0100, Mickaël Salaün wrote:
On 20/01/2021 04:43, Jarkko Sakkinen wrote:
quoted
On Thu, Jan 14, 2021 at 04:19:01PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
When looking for a blacklisted hash, bin2hex() is used to transform a
binary hash to an ascii (lowercase) hexadecimal string. This string is
then search for in the description of the keys from the blacklist
keyring. When adding a key to the blacklist keyring,
blacklist_vet_description() checks the hash prefix and the hexadecimal
string, but not that this string is lowercase. It is then valid to set
hashes with uppercase hexadecimal, which will be silently ignored by the
kernel.
Add an additional check to blacklist_vet_description() to check that
hexadecimal strings are in lowercase.
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <redacted>
---
Changes since v2:
* Cherry-pick v1 patch from
https://lore.kernel.org/lkml/2659836.1607940186@warthog.procyon.org.uk/
to rebase on v5.11-rc3.
* Rearrange Cc order.
---
certs/blacklist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -37,7 +37,7 @@ static int blacklist_vet_description(const char *desc)found_colon:desc++;for(;*desc;desc++){-if(!isxdigit(*desc))+if(!isxdigit(*desc)||isupper(*desc))return-EINVAL;n++;}
--
2.30.0
Shouldn't this rather convert the upper case to lower case? I don't like
the ABI break that this causes.
It doesn't break the ABI because keys loaded in the blacklist keyring
can only happen with builtin hashes. Moreover these builtin hashes will
be checked by patch 10/10 at build time.
Right the patches are just out of order then.
/Jarkko
This patch is also important to remove a false sense of security and
warns about mis-blacklisted certificates or binaries:
https://lore.kernel.org/lkml/c9664a67-61b7-6b4a-86d7-5aca9ff06fa5@digikod.net/
Hot-patching keys doesn't seem a good idea, especially when these keys
are signed. Moreover, it would bring additional complexity and will
require to change the core of the key management.
On Wed, Jan 20, 2021 at 12:57:55PM +0100, Mickaël Salaün wrote:
quoted
On 20/01/2021 06:19, Jarkko Sakkinen wrote:
quoted
On Thu, Jan 14, 2021 at 04:19:07PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes will be approved by the run time blacklist
description checks. This is useful to debug invalid hash formats, and
it make sure that previous hashes which could have been loaded in the
kernel (but ignored) are now noticed and deal with by the user.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
I get this with a self-signed cert:
certs/Makefile:18: *** target pattern contains no '%'. Stop.
CONFIG_SYSTEM_BLACKLIST_HASH_LIST="tbs:8eed1340eef37c1dc84d996406ad05c7dbb3eade19132d688408ca2f63904869"
As said in the Kconfig documentation for
CONFIG_SYSTEM_BLACKLIST_HASH_LIST, you need to provide a file with the
list, not to set the string directly in the configuration variable. This
patch series didn't change this behavior. The same kind of macros are
used for CONFIG_MODULE_SIG_KEY.
OK, the documentation just states that:
"Hashes to be preloaded into the system blacklist keyring"
No mention about a file. I'd add a patch to update this documentation.
I was referring to the full description:
config SYSTEM_BLACKLIST_HASH_LIST
string "Hashes to be preloaded into the system blacklist keyring"
depends on SYSTEM_BLACKLIST_KEYRING
help
If set, this option should be the filename of a list of hashes in the
form "<hash>", "<hash>", ... . This will be included into a C
wrapper to incorporate the list into the kernel. Each <hash> should
be a string of hex digits.
…but the short description doesn't mention filename.
quoted
quoted
I used the script in 10/10 to test this, which is another
reamark: the patches are in invalid order, as you need to
apply 10/10 before you can test 8/10.
I'll move patch 10/10 earlier but this kind of formatting was already
required (but silently ignored) for this option to be really taken into
account. Only the kernel code was available to understand how to
effectively create such hash.
From: Jarkko Sakkinen <jarkko@kernel.org> Date: 2021-01-21 15:23:13
On Thu, Jan 21, 2021 at 10:18:20AM +0100, Mickaël Salaün wrote:
On 21/01/2021 00:53, Jarkko Sakkinen wrote:
quoted
On Wed, Jan 20, 2021 at 12:57:55PM +0100, Mickaël Salaün wrote:
quoted
On 20/01/2021 06:19, Jarkko Sakkinen wrote:
quoted
On Thu, Jan 14, 2021 at 04:19:07PM +0100, Mickaël Salaün wrote:
quoted
From: Mickaël Salaün <redacted>
Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes will be approved by the run time blacklist
description checks. This is useful to debug invalid hash formats, and
it make sure that previous hashes which could have been loaded in the
kernel (but ignored) are now noticed and deal with by the user.
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Mickaël Salaün <redacted>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
I get this with a self-signed cert:
certs/Makefile:18: *** target pattern contains no '%'. Stop.
CONFIG_SYSTEM_BLACKLIST_HASH_LIST="tbs:8eed1340eef37c1dc84d996406ad05c7dbb3eade19132d688408ca2f63904869"
As said in the Kconfig documentation for
CONFIG_SYSTEM_BLACKLIST_HASH_LIST, you need to provide a file with the
list, not to set the string directly in the configuration variable. This
patch series didn't change this behavior. The same kind of macros are
used for CONFIG_MODULE_SIG_KEY.
OK, the documentation just states that:
"Hashes to be preloaded into the system blacklist keyring"
No mention about a file. I'd add a patch to update this documentation.
I was referring to the full description:
config SYSTEM_BLACKLIST_HASH_LIST
string "Hashes to be preloaded into the system blacklist keyring"
depends on SYSTEM_BLACKLIST_KEYRING
help
If set, this option should be the filename of a list of hashes in the
form "<hash>", "<hash>", ... . This will be included into a C
wrapper to incorporate the list into the kernel. Each <hash> should
be a string of hex digits.
…but the short description doesn't mention filename.
Aah.
Anyway, I'll test the next version. Now all should be clear how
to approach that. Thanks.
/Jarkko