Message ID | 1654714889-26728-14-git-send-email-deven.desai@linux.microsoft.com (mailing list archive) |
---|---|
State | Changes Requested, archived |
Delegated to: | Mike Snitzer |
Headers | show |
Series | Integrity Policy Enforcement LSM (IPE) | expand |
On Wed, Jun 08, 2022 at 12:01:25PM -0700, Deven Bowers wrote: > From: Fan Wu <wufan@linux.microsoft.com> > > fsverity represents a mechanism to support both integrity and > authenticity protection of a file, supporting both signed and unsigned > digests. > > An LSM which controls access to a resource based on authenticity and > integrity of said resource, can then use this data to make an informed > decision on the authorization (provided by the LSM's policy) of said > claim. > > This effectively allows the extension of a policy enforcement layer in > LSM for fsverity, allowing for more granular control of how a > particular authenticity claim can be used. For example, "all (built-in) > signed fsverity files should be allowed to execute, but only these > hashes are allowed to be loaded as kernel modules". > > This enforcement must be done in kernel space, as a userspace only > solution would fail a simple litmus test: Download a self-contained > malicious binary that never touches the userspace stack. This > binary would still be able to execute. > > Signed-off-by: Fan Wu <wufan@linux.microsoft.com> > Signed-off-by: Deven Bowers <deven.desai@linux.microsoft.com> The IMA support for fs-verity, which is now upstream, already does this (except that IMA isn't an LSM). It also doesn't rely on the fs-verity builtin signatures, which shouldn't really be used. Can you elaborate on how what you're doing is better? - Eric -- dm-devel mailing list dm-devel@redhat.com https://listman.redhat.com/mailman/listinfo/dm-devel
diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h index 629785c95007..e0d70235bbdc 100644 --- a/fs/verity/fsverity_private.h +++ b/fs/verity/fsverity_private.h @@ -114,7 +114,7 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params, unsigned int log_blocksize, const u8 *salt, size_t salt_size); -struct fsverity_info *fsverity_create_info(const struct inode *inode, +struct fsverity_info *fsverity_create_info(struct inode *inode, struct fsverity_descriptor *desc); void fsverity_set_info(struct inode *inode, struct fsverity_info *vi); diff --git a/fs/verity/open.c b/fs/verity/open.c index 81ff94442f7b..7e6fa52c0e9c 100644 --- a/fs/verity/open.c +++ b/fs/verity/open.c @@ -7,7 +7,9 @@ #include "fsverity_private.h" +#include <linux/security.h> #include <linux/slab.h> +#include <crypto/public_key.h> static struct kmem_cache *fsverity_info_cachep; @@ -146,7 +148,7 @@ static int compute_file_digest(struct fsverity_hash_alg *hash_alg, * appended signature), and check the signature if present. The * fsverity_descriptor must have already undergone basic validation. */ -struct fsverity_info *fsverity_create_info(const struct inode *inode, +struct fsverity_info *fsverity_create_info(struct inode *inode, struct fsverity_descriptor *desc) { struct fsverity_info *vi; @@ -182,6 +184,15 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode, err = fsverity_verify_signature(vi, desc->signature, le32_to_cpu(desc->sig_size)); + if (err) { + fsverity_err(inode, "Error %d verifying signature", err); + goto out; + } + + err = security_inode_setsecurity(inode, FS_VERITY_INODE_SEC_NAME, desc->signature, + le32_to_cpu(desc->sig_size), 0); + if (err == -EOPNOTSUPP) + err = 0; out: if (err) { fsverity_free_info(vi); diff --git a/fs/verity/signature.c b/fs/verity/signature.c index 143a530a8008..5d7b9496f9c4 100644 --- a/fs/verity/signature.c +++ b/fs/verity/signature.c @@ -9,6 +9,7 @@ #include <linux/cred.h> #include <linux/key.h> +#include <linux/security.h> #include <linux/slab.h> #include <linux/verification.h> diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index 7af030fa3c36..f37936b56150 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -251,4 +251,6 @@ static inline bool fsverity_active(const struct inode *inode) return fsverity_get_info(inode) != NULL; } +#define FS_VERITY_INODE_SEC_NAME "fsverity.inode-info" + #endif /* _LINUX_FSVERITY_H */