From 49b2ae70344bc3212aa268576cb15d903b32558e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 2 Oct 2018 08:33:08 +0200 Subject: fs: ubifs: Add authentication support This adds UBIFS authentication support. For now, we do not do any authentication even on authenticated UBIFS images. Since this behaviour is not what the user normally expects when mounting authenticated images we only do this when the user explicitly allows it in "global.ubifs.allow_authenticated_unauthenticated". If the flag is false then we refuse mounting such an image and return -EPERM instead. Signed-off-by: Sascha Hauer --- fs/ubifs/sb.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'fs/ubifs/sb.c') diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index a13f092eb0..9eb8064d72 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c @@ -220,7 +220,7 @@ failed: * code. Note, the user of this function is responsible of kfree()'ing the * returned superblock buffer. */ -struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) +static struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) { struct ubifs_sb_node *sup; int err; @@ -239,6 +239,39 @@ struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) return sup; } +static int authenticate_sb_node(struct ubifs_info *c, + const struct ubifs_sb_node *sup) +{ + unsigned int sup_flags = le32_to_cpu(sup->flags); + int authenticated = !!(sup_flags & UBIFS_FLG_AUTHENTICATION); + int hash_algo; + struct digest *digest; + + if (!authenticated) + return 0; + + if (!ubifs_allow_authenticated_unauthenticated) + return -EPERM; + + hash_algo = le16_to_cpu(sup->hash_algo); + if (hash_algo >= HASH_ALGO__LAST) { + ubifs_err(c, "superblock uses unknown hash algo %d", + hash_algo); + return -EINVAL; + } + + digest = digest_alloc_by_algo(hash_algo); + if (!digest) { + ubifs_err(c, "Cannot allocate hash algo %d", + hash_algo); + return -EINVAL; + } + + c->hash_len = digest_length(digest); + + return 0; +} + /* * removed in barebox int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) @@ -266,6 +299,8 @@ int ubifs_read_superblock(struct ubifs_info *c) if (IS_ERR(sup)) return PTR_ERR(sup); + c->sup_node = sup; + c->fmt_version = le32_to_cpu(sup->fmt_version); c->ro_compat_version = le32_to_cpu(sup->ro_compat_version); @@ -349,6 +384,10 @@ int ubifs_read_superblock(struct ubifs_info *c) c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH); c->encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION); + err = authenticate_sb_node(c, sup); + if (err) + goto out; + if ((sup_flags & ~UBIFS_FLG_MASK) != 0) { ubifs_err(c, "Unknown feature flags found: %#x", sup_flags & ~UBIFS_FLG_MASK); @@ -389,7 +428,6 @@ int ubifs_read_superblock(struct ubifs_info *c) err = validate_sb(c, sup); out: - kfree(sup); return err; } -- cgit v1.2.3