diff options
author | Eric Biggers <ebiggers@google.com> | 2023-06-04 04:23:12 +0200 |
---|---|---|
committer | Eric Biggers <ebiggers@google.com> | 2023-06-04 14:56:11 +0200 |
commit | 13e2408d02dd12a3b46bf8a29b3ae4f6119fc520 (patch) | |
tree | 2928a9e84be2405df60d6d916836b4f78d907f9d | |
parent | fsverity: don't use bio_first_page_all() in fsverity_verify_bio() (diff) | |
download | linux-13e2408d02dd12a3b46bf8a29b3ae4f6119fc520.tar.xz linux-13e2408d02dd12a3b46bf8a29b3ae4f6119fc520.zip |
fsverity: simplify error handling in verify_data_block()
Clean up the error handling in verify_data_block() to (a) eliminate the
'err' variable which has caused some confusion because the function
actually returns a bool, (b) reduce the compiled code size slightly, and
(c) execute one fewer branch in the success case.
Link: https://lore.kernel.org/r/20230604022312.48532-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
-rw-r--r-- | fs/verity/verify.c | 55 |
1 files changed, 21 insertions, 34 deletions
diff --git a/fs/verity/verify.c b/fs/verity/verify.c index cf40e2fe6ace..433cef51f5f6 100644 --- a/fs/verity/verify.c +++ b/fs/verity/verify.c @@ -12,23 +12,6 @@ static struct workqueue_struct *fsverity_read_workqueue; -static inline int cmp_hashes(const struct fsverity_info *vi, - const u8 *want_hash, const u8 *real_hash, - u64 data_pos, int level) -{ - const unsigned int hsize = vi->tree_params.digest_size; - - if (memcmp(want_hash, real_hash, hsize) == 0) - return 0; - - fsverity_err(vi->inode, - "FILE CORRUPTED! pos=%llu, level=%d, want_hash=%s:%*phN, real_hash=%s:%*phN", - data_pos, level, - vi->tree_params.hash_alg->name, hsize, want_hash, - vi->tree_params.hash_alg->name, hsize, real_hash); - return -EBADMSG; -} - /* * Returns true if the hash block with index @hblock_idx in the tree, located in * @hpage, has already been verified. @@ -131,7 +114,6 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi, * index of that block's hash within the current level. */ u64 hidx = data_pos >> params->log_blocksize; - int err; /* Up to 1 + FS_VERITY_MAX_LEVELS pages may be mapped at once */ BUILD_BUG_ON(1 + FS_VERITY_MAX_LEVELS > KM_MAX_IDX); @@ -191,11 +173,10 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi, hpage_idx, level == 0 ? min(max_ra_pages, params->tree_pages - hpage_idx) : 0); if (IS_ERR(hpage)) { - err = PTR_ERR(hpage); fsverity_err(inode, - "Error %d reading Merkle tree page %lu", - err, hpage_idx); - goto out; + "Error %ld reading Merkle tree page %lu", + PTR_ERR(hpage), hpage_idx); + goto error; } haddr = kmap_local_page(hpage) + hblock_offset_in_page; if (is_hash_block_verified(vi, hpage, hblock_idx)) { @@ -221,12 +202,10 @@ descend: unsigned long hblock_idx = hblocks[level - 1].index; unsigned int hoffset = hblocks[level - 1].hoffset; - err = fsverity_hash_block(params, inode, haddr, real_hash); - if (err) - goto out; - err = cmp_hashes(vi, want_hash, real_hash, data_pos, level - 1); - if (err) - goto out; + if (fsverity_hash_block(params, inode, haddr, real_hash) != 0) + goto error; + if (memcmp(want_hash, real_hash, hsize) != 0) + goto corrupted; /* * Mark the hash block as verified. This must be atomic and * idempotent, as the same hash block might be verified by @@ -243,16 +222,24 @@ descend: } /* Finally, verify the data block. */ - err = fsverity_hash_block(params, inode, data, real_hash); - if (err) - goto out; - err = cmp_hashes(vi, want_hash, real_hash, data_pos, -1); -out: + if (fsverity_hash_block(params, inode, data, real_hash) != 0) + goto error; + if (memcmp(want_hash, real_hash, hsize) != 0) + goto corrupted; + return true; + +corrupted: + fsverity_err(inode, + "FILE CORRUPTED! pos=%llu, level=%d, want_hash=%s:%*phN, real_hash=%s:%*phN", + data_pos, level - 1, + params->hash_alg->name, hsize, want_hash, + params->hash_alg->name, hsize, real_hash); +error: for (; level > 0; level--) { kunmap_local(hblocks[level - 1].addr); put_page(hblocks[level - 1].page); } - return err == 0; + return false; } static bool |