fsverity: skip PKCS#7 parser when keyring is empty
Eric Biggers
maintainerPATCH v3 1/1 fsverity: skip PKCS#7 parser when keyring is empty
From: Eric Biggers <[email protected]>
If an fsverity builtin signature is given for a file but the ".fs-verity" keyring is empty, there's no real reason to run the PKCS#7 parser. Skip this to avoid the PKCS#7 attack surface when builtin signature support is configured into the kernel but is not being used.
This is a hardening improvement, not a fix per se, but I've added Fixes and Cc stable to get it out to more users.
---
v3: improve the error message slightly
v2: check keyring and return early before allocating formatted digest
fs/verity/signature.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
fs/verity/signature.c +16 -0
@@ -55,20 +55,36 @@ int fsverity_verify_signature(const struct fsverity_info *vi,if (sig_size ==0 ) {if (fsverity_require_signatures) {fsverity_err (inode,"require_signatures=1, rejecting unsigned file!" );return -EPERM ; }return 0 ; } +if (fsverity_keyring->keys.nr_leaves_on_tree ==0 ) { +/* +* The ".fs-verity" keyring is empty, due to builtin signatures +* being supported by the kernel but not actually being used. +* In this case, verify_pkcs7_signature() would always return an +* error, usually ENOKEY. It could also be EBADMSG if the +* PKCS#7 is malformed, but that isn't very important to +* distinguish. So, just skip to ENOKEY to avoid the attack +* surface of the PKCS#7 parser, which would otherwise be +* reachable by any task able to execute FS_IOC_ENABLE_VERITY. +*/ +fsverity_err (inode, +"fs-verity keyring is empty, rejecting signed file!" ); +return -ENOKEY ; + } + d =kzalloc (sizeof (*d) + hash_alg->digest_size,GFP_KERNEL );if (!d)return -ENOMEM ;memcpy (d->magic,"FSVerity" ,8 ); d->digest_algorithm =cpu_to_le16 (hash_alg - fsverity_hash_algs); d->digest_size =cpu_to_le16 (hash_alg->digest_size);memcpy (d->digest, vi->file_digest, hash_alg->digest_size); err = verify_pkcs7_signature(d, sizeof(*d) + hash_alg->digest_size, signature, sig_size, fsverity_keyring,
base-commit: 456ae5fe9b448f44ebe98b391a3bae9c75df465e
Signature · 1 line
2.41.0
Quoted 64 lines · Eric Biggers
From: Eric Biggers <[email protected]>
If an fsverity builtin signature is given for a file but the ".fs-verity" keyring is empty, there's no real reason to run the PKCS#7 parser. Skip this to avoid the PKCS#7 attack surface when builtin signature support is configured into the kernel but is not being used.
This is a hardening improvement, not a fix per se, but I've added Fixes and Cc stable to get it out to more users.
Fixes 432434c9f8e1 ("fs-verity: support builtin file signatures")Reviewed-by Jarkko Sakkinen <[email protected]>Signed-off-by Eric Biggers <[email protected]>---
v3: improve the error message slightly
v2: check keyring and return early before allocating formatted digestfs/verity/signature.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)fs/verity/signature.c +16
-0@@ -55,20 +55,36 @@ int fsverity_verify_signature(const struct fsverity_info *vi,if (sig_size ==0 ) {if (fsverity_require_signatures) {fsverity_err (inode,"require_signatures=1, rejecting unsigned file!" );return -EPERM ; }return 0 ; } +if (fsverity_keyring->keys.nr_leaves_on_tree ==0 ) { +/* +* The ".fs-verity" keyring is empty, due to builtin signatures +* being supported by the kernel but not actually being used. +* In this case, verify_pkcs7_signature() would always return an +* error, usually ENOKEY. It could also be EBADMSG if the +* PKCS#7 is malformed, but that isn't very important to +* distinguish. So, just skip to ENOKEY to avoid the attack +* surface of the PKCS#7 parser, which would otherwise be +* reachable by any task able to execute FS_IOC_ENABLE_VERITY. +*/ +fsverity_err (inode, +"fs-verity keyring is empty, rejecting signed file!" ); +return -ENOKEY ; + } + d =kzalloc (sizeof (*d) + hash_alg->digest_size,GFP_KERNEL );if (!d)return -ENOMEM ;memcpy (d->magic,"FSVerity" ,8 ); d->digest_algorithm =cpu_to_le16 (hash_alg - fsverity_hash_algs); d->digest_size =cpu_to_le16 (hash_alg->digest_size);memcpy (d->digest, vi->file_digest, hash_alg->digest_size); err = verify_pkcs7_signature(d, sizeof(*d) + hash_alg->digest_size, signature, sig_size, fsverity_keyring,
Quoted 3 lines
base-commit:
456ae5fe9b448f44ebe98b391a3bae9c75df465eSignature · 1 line
2.41.0
BR, Jarkko