Message ID | 171069246170.2684506.16175333193381403848.stgit@frogsfrogsfrogs (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/40] fsverity: remove hash page spin lock | expand |
On Sun, Mar 17, 2024 at 09:27:34AM -0700, Darrick J. Wong wrote: > diff --git a/fs/verity/open.c b/fs/verity/open.c > index 7a86407732c4..433a70eeca55 100644 > --- a/fs/verity/open.c > +++ b/fs/verity/open.c > @@ -144,6 +144,13 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params, > goto out_err; > } > > + err = fsverity_hash_buffer(params->hash_alg, page_address(ZERO_PAGE(0)), > + i_blocksize(inode), params->zero_digest); > + if (err) { > + fsverity_err(inode, "Error %d computing zero digest", err); > + goto out_err; > + } This doesn't take the salt into account. Also it's using the wrong block size (filesystem block size instead of Merkle tree block size). How about using fsverity_hash_block()? - Eric
On Mon, Mar 18, 2024 at 09:38:47AM -0700, Eric Biggers wrote: > On Sun, Mar 17, 2024 at 09:27:34AM -0700, Darrick J. Wong wrote: > > diff --git a/fs/verity/open.c b/fs/verity/open.c > > index 7a86407732c4..433a70eeca55 100644 > > --- a/fs/verity/open.c > > +++ b/fs/verity/open.c > > @@ -144,6 +144,13 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params, > > goto out_err; > > } > > > > + err = fsverity_hash_buffer(params->hash_alg, page_address(ZERO_PAGE(0)), > > + i_blocksize(inode), params->zero_digest); > > + if (err) { > > + fsverity_err(inode, "Error %d computing zero digest", err); > > + goto out_err; > > + } > > This doesn't take the salt into account. Also it's using the wrong block size > (filesystem block size instead of Merkle tree block size). > > How about using fsverity_hash_block()? /me looks at build_merkle_tree again, realizes that it calls hash_one_block on params->block_size bytes of file data. IOWs, fsverity_hash_block is indeed the correct function to call here. Thanks for the correction! --D > - Eric
diff --git a/fs/verity/enable.c b/fs/verity/enable.c index 8dcfefc848ee..06b769dd1bdf 100644 --- a/fs/verity/enable.c +++ b/fs/verity/enable.c @@ -52,6 +52,8 @@ static int write_merkle_tree_block(struct inode *inode, const u8 *buf, { struct fsverity_writemerkle req = { .inode = inode, + .zero_digest = params->zero_digest, + .digest_size = params->digest_size, }; u64 pos = (u64)index << params->log_blocksize; int err; diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h index de8798f141d4..195a92f203bb 100644 --- a/fs/verity/fsverity_private.h +++ b/fs/verity/fsverity_private.h @@ -47,6 +47,8 @@ struct merkle_tree_params { u64 tree_size; /* Merkle tree size in bytes */ unsigned long tree_pages; /* Merkle tree size in pages */ + u8 zero_digest[FS_VERITY_MAX_DIGEST_SIZE]; /* hash of zeroed data block */ + /* * Starting block index for each tree level, ordered from leaf level (0) * to root level ('num_levels - 1') diff --git a/fs/verity/open.c b/fs/verity/open.c index 7a86407732c4..433a70eeca55 100644 --- a/fs/verity/open.c +++ b/fs/verity/open.c @@ -144,6 +144,13 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params, goto out_err; } + err = fsverity_hash_buffer(params->hash_alg, page_address(ZERO_PAGE(0)), + i_blocksize(inode), params->zero_digest); + if (err) { + fsverity_err(inode, "Error %d computing zero digest", err); + goto out_err; + } + params->tree_size = offset << log_blocksize; params->tree_pages = PAGE_ALIGN(params->tree_size) >> PAGE_SHIFT; return 0; diff --git a/fs/verity/verify.c b/fs/verity/verify.c index a61d1c99c485..494225f60608 100644 --- a/fs/verity/verify.c +++ b/fs/verity/verify.c @@ -409,6 +409,8 @@ int fsverity_read_merkle_tree_block(struct inode *inode, .num_levels = params->num_levels, .log_blocksize = params->log_blocksize, .ra_bytes = ra_bytes, + .zero_digest = params->zero_digest, + .digest_size = params->digest_size, }; block->verified = false; diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index 0dded1fcf2b1..da23f1e30151 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -66,6 +66,8 @@ struct fsverity_blockbuf { * if the page at @block->offset isn't already cached. * Implementations may ignore this argument; it's only a * performance optimization. + * @zero_digest: the hash for a data block of zeroes + * @digest_size: size of zero_digest */ struct fsverity_readmerkle { struct inode *inode; @@ -73,6 +75,8 @@ struct fsverity_readmerkle { int level; int num_levels; u8 log_blocksize; + const u8 *zero_digest; + unsigned int digest_size; }; /** @@ -81,12 +85,16 @@ struct fsverity_readmerkle { * @level: level of the block; level 0 are the leaves * @num_levels: number of levels in the tree total * @log_blocksize: log2 of the size of the block + * @zero_digest: the hash for a data block of zeroes + * @digest_size: size of zero_digest */ struct fsverity_writemerkle { struct inode *inode; int level; int num_levels; u8 log_blocksize; + const u8 *zero_digest; + unsigned int digest_size; }; /* Verity operations for filesystems */