History

Merge tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fsverity/linux

Pull fsverity updates from Eric Biggers: "Several cleanups and fixes for fs/verity/, including a couple minor fixes to the changes in 6.3 that added support for Merkle tree block sizes less than the page size" * tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fsverity/linux: fsverity: reject FS_IOC_ENABLE_VERITY on mode 3 fds fsverity: explicitly check for buffer overflow in build_merkle_tree() fsverity: use WARN_ON_ONCE instead of WARN_ON fs-verity: simplify sysctls with register_sysctl() fs/buffer.c: use b_folio for fsverity work

Linus Torvalds committed 3 years ago

Commit c3558a62 parents dbe0e78 04839136 files · +30 −21Browse files

Unified · Split

6 files
  1. fs/buffer.c +4 −5
  2. fs/verity/enable.c +19 −2
  3. fs/verity/hash_algs.c +2 −2
  4. fs/verity/open.c +1 −1
  5. fs/verity/signature.c +1 −8
  6. include/linux/fsverity.h +3 −3
fs/buffer.c+4−5
@@ -308,20 +308,19 @@ static void verify_bh(struct work_struct *work) · 307 unmodified lines
308 struct buffer_head *bh = ctx->bh;308 struct buffer_head *bh = ctx->bh;
309 bool valid;309 bool valid;
310 310
311 valid = fsverity_verify_blocks(page_folio(bh->b_page), bh->b_size,311 valid = fsverity_verify_blocks(bh->b_folio, bh->b_size, bh_offset(bh));
312 bh_offset(bh));
313 end_buffer_async_read(bh, valid);312 end_buffer_async_read(bh, valid);
314 kfree(ctx);313 kfree(ctx);
315}314}
316 315
317static bool need_fsverity(struct buffer_head *bh)316static bool need_fsverity(struct buffer_head *bh)
318{317{
319 struct page *page = bh->b_page;318 struct folio *folio = bh->b_folio;
320 struct inode *inode = page->mapping->host;319 struct inode *inode = folio->mapping->host;
321 320
322 return fsverity_active(inode) &&321 return fsverity_active(inode) &&
323 /* needed by ext4 */322 /* needed by ext4 */
324 page->index < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);323 folio->index < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
325}324}
326 325
327static void decrypt_bh(struct work_struct *work)326static void decrypt_bh(struct work_struct *work)
fs/verity/enable.c+19−2
@@ -13,6 +13,7 @@ · 12 unmodified lines
13 13
14struct block_buffer {14struct block_buffer {
15 u32 filled;15 u32 filled;
16 bool is_root_hash;
16 u8 *data;17 u8 *data;
17};18};
18 19
@@ -24,6 +25,14 @@ static int hash_one_block(struct inode *inode, · 5 unmodified lines
24 struct block_buffer *next = cur + 1;25 struct block_buffer *next = cur + 1;
25 int err;26 int err;
26 27
28 /*
29 * Safety check to prevent a buffer overflow in case of a filesystem bug
30 * that allows the file size to change despite deny_write_access(), or a
31 * bug in the Merkle tree logic itself
32 */
33 if (WARN_ON_ONCE(next->is_root_hash && next->filled != 0))
34 return -EINVAL;
35
27 /* Zero-pad the block if it's shorter than the block size. */36 /* Zero-pad the block if it's shorter than the block size. */
28 memset(&cur->data[cur->filled], 0, params->block_size - cur->filled);37 memset(&cur->data[cur->filled], 0, params->block_size - cur->filled);
29 38
@@ -97,6 +106,7 @@ static int build_merkle_tree(struct file *filp, · 67 unmodified lines
97 }106 }
98 }107 }
99 buffers[num_levels].data = root_hash;108 buffers[num_levels].data = root_hash;
109 buffers[num_levels].is_root_hash = true;
100 110
101 BUILD_BUG_ON(sizeof(level_offset) != sizeof(params->level_start));111 BUILD_BUG_ON(sizeof(level_offset) != sizeof(params->level_start));
102 memcpy(level_offset, params->level_start, sizeof(level_offset));112 memcpy(level_offset, params->level_start, sizeof(level_offset));
@@ -165,7 +175,7 @@ static int build_merkle_tree(struct file *filp, · 62 unmodified lines
165 }175 }
166 }176 }
167 /* The root hash was filled by the last call to hash_one_block(). */177 /* The root hash was filled by the last call to hash_one_block(). */
168 if (WARN_ON(buffers[num_levels].filled != params->digest_size)) {178 if (WARN_ON_ONCE(buffers[num_levels].filled != params->digest_size)) {
169 err = -EINVAL;179 err = -EINVAL;
170 goto out;180 goto out;
171 }181 }
@@ -277,7 +287,7 @@ static int enable_verity(struct file *filp, · 105 unmodified lines
277 fsverity_err(inode, "%ps() failed with err %d",287 fsverity_err(inode, "%ps() failed with err %d",
278 vops->end_enable_verity, err);288 vops->end_enable_verity, err);
279 fsverity_free_info(vi);289 fsverity_free_info(vi);
280 } else if (WARN_ON(!IS_VERITY(inode))) {290 } else if (WARN_ON_ONCE(!IS_VERITY(inode))) {
281 err = -EINVAL;291 err = -EINVAL;
282 fsverity_free_info(vi);292 fsverity_free_info(vi);
283 } else {293 } else {
@@ -347,6 +357,13 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg) · 63 unmodified lines
347 err = file_permission(filp, MAY_WRITE);357 err = file_permission(filp, MAY_WRITE);
348 if (err)358 if (err)
349 return err;359 return err;
360 /*
361 * __kernel_read() is used while building the Merkle tree. So, we can't
362 * allow file descriptors that were opened for ioctl access only, using
363 * the special nonstandard access mode 3. O_RDONLY only, please!
364 */
365 if (!(filp->f_mode & FMODE_READ))
366 return -EBADF;
350 367
351 if (IS_APPEND(inode))368 if (IS_APPEND(inode))
352 return -EPERM;369 return -EPERM;
fs/verity/hash_algs.c+2−2
@@ -84,9 +84,9 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode, · 83 unmodified lines
84 }84 }
85 85
86 err = -EINVAL;86 err = -EINVAL;
87 if (WARN_ON(alg->digest_size != crypto_ahash_digestsize(tfm)))87 if (WARN_ON_ONCE(alg->digest_size != crypto_ahash_digestsize(tfm)))
88 goto err_free_tfm;88 goto err_free_tfm;
89 if (WARN_ON(alg->block_size != crypto_ahash_blocksize(tfm)))89 if (WARN_ON_ONCE(alg->block_size != crypto_ahash_blocksize(tfm)))
90 goto err_free_tfm;90 goto err_free_tfm;
91 91
92 err = mempool_init_kmalloc_pool(&alg->req_pool, 1,92 err = mempool_init_kmalloc_pool(&alg->req_pool, 1,
fs/verity/open.c+1−1
@@ -83,7 +83,7 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params, · 82 unmodified lines
83 params->log_blocks_per_page = PAGE_SHIFT - log_blocksize;83 params->log_blocks_per_page = PAGE_SHIFT - log_blocksize;
84 params->blocks_per_page = 1 << params->log_blocks_per_page;84 params->blocks_per_page = 1 << params->log_blocks_per_page;
85 85
86 if (WARN_ON(!is_power_of_2(params->digest_size))) {86 if (WARN_ON_ONCE(!is_power_of_2(params->digest_size))) {
87 err = -EINVAL;87 err = -EINVAL;
88 goto out_err;88 goto out_err;
89 }89 }
fs/verity/signature.c+1−8
@@ -88,12 +88,6 @@ int fsverity_verify_signature(const struct fsverity_info *vi, · 87 unmodified lines
88#ifdef CONFIG_SYSCTL88#ifdef CONFIG_SYSCTL
89static struct ctl_table_header *fsverity_sysctl_header;89static struct ctl_table_header *fsverity_sysctl_header;
90 90
91static const struct ctl_path fsverity_sysctl_path[] = {
92 { .procname = "fs", },
93 { .procname = "verity", },
94 { }
95};
96
97static struct ctl_table fsverity_sysctl_table[] = {91static struct ctl_table fsverity_sysctl_table[] = {
98 {92 {
99 .procname = "require_signatures",93 .procname = "require_signatures",
@@ -109,8 +103,7 @@ static struct ctl_table fsverity_sysctl_table[] = { · 9 unmodified lines
109 103
110static int __init fsverity_sysctl_init(void)104static int __init fsverity_sysctl_init(void)
111{105{
112 fsverity_sysctl_header = register_sysctl_paths(fsverity_sysctl_path,106 fsverity_sysctl_header = register_sysctl("fs/verity", fsverity_sysctl_table);
113 fsverity_sysctl_table);
114 if (!fsverity_sysctl_header) {107 if (!fsverity_sysctl_header) {
115 pr_err("sysctl registration failed!\n");108 pr_err("sysctl registration failed!\n");
116 return -ENOMEM;109 return -ENOMEM;
include/linux/fsverity.h+3−3
@@ -233,18 +233,18 @@ static inline int fsverity_ioctl_read_metadata(struct file *filp, · 232 unmodified lines
233static inline bool fsverity_verify_blocks(struct folio *folio, size_t len,233static inline bool fsverity_verify_blocks(struct folio *folio, size_t len,
234 size_t offset)234 size_t offset)
235{235{
236 WARN_ON(1);236 WARN_ON_ONCE(1);
237 return false;237 return false;
238}238}
239 239
240static inline void fsverity_verify_bio(struct bio *bio)240static inline void fsverity_verify_bio(struct bio *bio)
241{241{
242 WARN_ON(1);242 WARN_ON_ONCE(1);
243}243}
244 244
245static inline void fsverity_enqueue_verify_work(struct work_struct *work)245static inline void fsverity_enqueue_verify_work(struct work_struct *work)
246{246{
247 WARN_ON(1);247 WARN_ON_ONCE(1);
248}248}
249 249
250#endif /* !CONFIG_FS_VERITY */250#endif /* !CONFIG_FS_VERITY */