diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-10-02 08:33:08 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-04-24 13:24:57 +0200 |
commit | 49b2ae70344bc3212aa268576cb15d903b32558e (patch) | |
tree | 33bcab6833dd5c3d6fbbb25e5bae3468052f10b8 /fs/ubifs/sb.c | |
parent | ea569a0afd6a2e9a84418cd18ddeaeefaa5eae39 (diff) | |
download | barebox-49b2ae70344bc3212aa268576cb15d903b32558e.tar.gz barebox-49b2ae70344bc3212aa268576cb15d903b32558e.tar.xz |
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 <s.hauer@pengutronix.de>
Diffstat (limited to 'fs/ubifs/sb.c')
-rw-r--r-- | fs/ubifs/sb.c | 42 |
1 files changed, 40 insertions, 2 deletions
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; } |