• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2020 Google LLC
4  */
5 
6 /*
7  * fs-verity integration into incfs
8  *
9  * Since incfs has its own merkle tree implementation, most of fs-verity code
10  * is not needed. The key part that is needed is the signature check, since
11  * that is based on the private /proc/sys/fs/verity/require_signatures value
12  * and a private keyring. Thus the first change is to modify verity code to
13  * export a version of fsverity_verify_signature.
14  *
15  * fs-verity integration then consists of the following modifications:
16  *
17  * 1. Add the (optional) verity signature to the incfs file format
18  * 2. Add a pointer to the digest of the fs-verity descriptor struct to the
19  *    data_file struct that incfs attaches to each file inode.
20  * 3. Add the following ioclts:
21  *  - FS_IOC_ENABLE_VERITY
22  *  - FS_IOC_GETFLAGS
23  *  - FS_IOC_MEASURE_VERITY
24  * 4. When FS_IOC_ENABLE_VERITY is called on a non-verity file, the
25  *    fs-verity descriptor struct is populated and digested. If it passes the
26  *    signature check or the signature is NULL and
27  *    fs.verity.require_signatures=0, then the S_VERITY flag is set and the
28  *    xattr incfs.verity is set. If the signature is non-NULL, an
29  *    INCFS_MD_VERITY_SIGNATURE is added to the backing file containing the
30  *    signature.
31  * 5. When a file with an incfs.verity xattr's inode is initialized, the
32  *    inode’s S_VERITY flag is set.
33  * 6. When a file with the S_VERITY flag set on its inode is opened, the
34  *    data_file is checked for its verity digest. If the file doesn’t have a
35  *    digest, the file’s digest is calculated as above, checked, and set, or the
36  *    open is denied if it is not valid.
37  * 7. FS_IOC_GETFLAGS simply returns the value of the S_VERITY flag
38  * 8. FS_IOC_MEASURE_VERITY simply returns the cached digest
39  * 9. The final complication is that if FS_IOC_ENABLE_VERITY is called on a file
40  *    which doesn’t have a merkle tree, the merkle tree is calculated before the
41  *    rest of the process is completed.
42  */
43 
44 #include <crypto/hash.h>
45 #include <crypto/sha.h>
46 #include <linux/fsverity.h>
47 #include <linux/mount.h>
48 
49 #include "verity.h"
50 
51 #include "data_mgmt.h"
52 #include "format.h"
53 #include "integrity.h"
54 #include "vfs.h"
55 
56 #define FS_VERITY_MAX_SIGNATURE_SIZE	16128
57 
incfs_get_root_hash(struct file * filp,u8 * root_hash)58 static int incfs_get_root_hash(struct file *filp, u8 *root_hash)
59 {
60 	struct data_file *df = get_incfs_data_file(filp);
61 
62 	if (!df)
63 		return -EINVAL;
64 
65 	memcpy(root_hash, df->df_hash_tree->root_hash,
66 	       df->df_hash_tree->alg->digest_size);
67 
68 	return 0;
69 }
70 
incfs_end_enable_verity(struct file * filp,u8 * sig,size_t sig_size)71 static int incfs_end_enable_verity(struct file *filp, u8 *sig, size_t sig_size)
72 {
73 	struct inode *inode = file_inode(filp);
74 	struct mem_range signature = {
75 		.data = sig,
76 		.len = sig_size,
77 	};
78 	struct data_file *df = get_incfs_data_file(filp);
79 	struct backing_file_context *bfc;
80 	int error;
81 	struct incfs_df_verity_signature *vs = NULL;
82 	loff_t offset;
83 
84 	if (!df || !df->df_backing_file_context)
85 		return -EFSCORRUPTED;
86 
87 	if (sig) {
88 		vs = kzalloc(sizeof(*vs), GFP_NOFS);
89 		if (!vs)
90 			return -ENOMEM;
91 	}
92 
93 	bfc = df->df_backing_file_context;
94 	error = mutex_lock_interruptible(&bfc->bc_mutex);
95 	if (error)
96 		goto out;
97 
98 	error = incfs_write_verity_signature_to_backing_file(bfc, signature,
99 							     &offset);
100 	mutex_unlock(&bfc->bc_mutex);
101 	if (error)
102 		goto out;
103 
104 	/*
105 	 * Set verity xattr so we can set S_VERITY without opening backing file
106 	 */
107 	error = vfs_setxattr(bfc->bc_file->f_path.dentry,
108 			     INCFS_XATTR_VERITY_NAME, NULL, 0, XATTR_CREATE);
109 	if (error) {
110 		pr_warn("incfs: error setting verity xattr: %d\n", error);
111 		goto out;
112 	}
113 
114 	if (sig) {
115 		*vs = (struct incfs_df_verity_signature) {
116 			.size = signature.len,
117 			.offset = offset,
118 		};
119 
120 		df->df_verity_signature = vs;
121 		vs = NULL;
122 	}
123 
124 	inode_set_flags(inode, S_VERITY, S_VERITY);
125 
126 out:
127 	kfree(vs);
128 	return error;
129 }
130 
incfs_compute_file_digest(struct incfs_hash_alg * alg,struct fsverity_descriptor * desc,u8 * digest)131 static int incfs_compute_file_digest(struct incfs_hash_alg *alg,
132 				struct fsverity_descriptor *desc,
133 				u8 *digest)
134 {
135 	SHASH_DESC_ON_STACK(d, alg->shash);
136 
137 	d->tfm = alg->shash;
138 	return crypto_shash_digest(d, (u8 *)desc, sizeof(*desc), digest);
139 }
140 
incfs_convert_fsverity_hash_alg(int hash_alg)141 static enum incfs_hash_tree_algorithm incfs_convert_fsverity_hash_alg(
142 								int hash_alg)
143 {
144 	switch (hash_alg) {
145 	case FS_VERITY_HASH_ALG_SHA256:
146 		return INCFS_HASH_TREE_SHA256;
147 	default:
148 		return -EINVAL;
149 	}
150 }
151 
incfs_get_verity_digest(struct inode * inode)152 static struct mem_range incfs_get_verity_digest(struct inode *inode)
153 {
154 	struct inode_info *node = get_incfs_node(inode);
155 	struct data_file *df;
156 	struct mem_range verity_file_digest;
157 
158 	if (!node) {
159 		pr_warn("Invalid inode\n");
160 		return range(NULL, 0);
161 	}
162 
163 	df = node->n_file;
164 
165 	/*
166 	 * Pairs with the cmpxchg_release() in incfs_set_verity_digest().
167 	 * I.e., another task may publish ->df_verity_file_digest concurrently,
168 	 * executing a RELEASE barrier.  We need to use smp_load_acquire() here
169 	 * to safely ACQUIRE the memory the other task published.
170 	 */
171 	verity_file_digest.data = smp_load_acquire(
172 					&df->df_verity_file_digest.data);
173 	verity_file_digest.len = df->df_verity_file_digest.len;
174 	return verity_file_digest;
175 }
176 
incfs_set_verity_digest(struct inode * inode,struct mem_range verity_file_digest)177 static void incfs_set_verity_digest(struct inode *inode,
178 				     struct mem_range verity_file_digest)
179 {
180 	struct inode_info *node = get_incfs_node(inode);
181 	struct data_file *df;
182 
183 	if (!node) {
184 		pr_warn("Invalid inode\n");
185 		kfree(verity_file_digest.data);
186 		return;
187 	}
188 
189 	df = node->n_file;
190 	df->df_verity_file_digest.len = verity_file_digest.len;
191 
192 	/*
193 	 * Multiple tasks may race to set ->df_verity_file_digest.data, so use
194 	 * cmpxchg_release().  This pairs with the smp_load_acquire() in
195 	 * incfs_get_verity_digest().  I.e., here we publish
196 	 * ->df_verity_file_digest.data, with a RELEASE barrier so that other
197 	 * tasks can ACQUIRE it.
198 	 */
199 	if (cmpxchg_release(&df->df_verity_file_digest.data, NULL,
200 			    verity_file_digest.data) != NULL)
201 		/* Lost the race, so free the file_digest we allocated. */
202 		kfree(verity_file_digest.data);
203 }
204 
205 /*
206  * Calculate the digest of the fsverity_descriptor. The signature (if present)
207  * is also checked.
208  */
incfs_calc_verity_digest_from_desc(const struct inode * inode,struct fsverity_descriptor * desc,u8 * signature,size_t sig_size)209 static struct mem_range incfs_calc_verity_digest_from_desc(
210 					const struct inode *inode,
211 					struct fsverity_descriptor *desc,
212 					u8 *signature, size_t sig_size)
213 {
214 	enum incfs_hash_tree_algorithm incfs_hash_alg;
215 	struct mem_range verity_file_digest;
216 	int err;
217 	struct incfs_hash_alg *hash_alg;
218 
219 	incfs_hash_alg = incfs_convert_fsverity_hash_alg(desc->hash_algorithm);
220 	if (incfs_hash_alg < 0)
221 		return range(ERR_PTR(incfs_hash_alg), 0);
222 
223 	hash_alg = incfs_get_hash_alg(incfs_hash_alg);
224 	if (IS_ERR(hash_alg))
225 		return range((u8 *)hash_alg, 0);
226 
227 	verity_file_digest = range(kzalloc(hash_alg->digest_size, GFP_KERNEL),
228 				   hash_alg->digest_size);
229 	if (!verity_file_digest.data)
230 		return range(ERR_PTR(-ENOMEM), 0);
231 
232 	err = incfs_compute_file_digest(hash_alg, desc,
233 					verity_file_digest.data);
234 	if (err) {
235 		pr_err("Error %d computing file digest", err);
236 		goto out;
237 	}
238 	pr_debug("Computed file digest: %s:%*phN\n",
239 		 hash_alg->name, (int) verity_file_digest.len,
240 		 verity_file_digest.data);
241 
242 	err = __fsverity_verify_signature(inode, signature, sig_size,
243 					  verity_file_digest.data,
244 					  desc->hash_algorithm);
245 out:
246 	if (err) {
247 		kfree(verity_file_digest.data);
248 		verity_file_digest = range(ERR_PTR(err), 0);
249 	}
250 	return verity_file_digest;
251 }
252 
incfs_get_fsverity_descriptor(struct file * filp,int hash_algorithm)253 static struct fsverity_descriptor *incfs_get_fsverity_descriptor(
254 					struct file *filp, int hash_algorithm)
255 {
256 	struct inode *inode = file_inode(filp);
257 	struct fsverity_descriptor *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
258 	int err;
259 
260 	if (!desc)
261 		return ERR_PTR(-ENOMEM);
262 
263 	*desc = (struct fsverity_descriptor) {
264 		.version = 1,
265 		.hash_algorithm = hash_algorithm,
266 		.log_blocksize = ilog2(INCFS_DATA_FILE_BLOCK_SIZE),
267 		.data_size = cpu_to_le64(inode->i_size),
268 	};
269 
270 	err = incfs_get_root_hash(filp, desc->root_hash);
271 	if (err) {
272 		kfree(desc);
273 		return ERR_PTR(err);
274 	}
275 
276 	return desc;
277 }
278 
incfs_calc_verity_digest(struct inode * inode,struct file * filp,u8 * signature,size_t signature_size,int hash_algorithm)279 static struct mem_range incfs_calc_verity_digest(
280 					struct inode *inode, struct file *filp,
281 					u8 *signature, size_t signature_size,
282 					int hash_algorithm)
283 {
284 	struct fsverity_descriptor *desc = incfs_get_fsverity_descriptor(filp,
285 							hash_algorithm);
286 	struct mem_range verity_file_digest;
287 
288 	if (IS_ERR(desc))
289 		return range((u8 *)desc, 0);
290 	verity_file_digest = incfs_calc_verity_digest_from_desc(inode, desc,
291 						signature, signature_size);
292 	kfree(desc);
293 	return verity_file_digest;
294 }
295 
incfs_build_merkle_tree(struct file * f,struct data_file * df,struct backing_file_context * bfc,struct mtree * hash_tree,loff_t hash_offset,struct incfs_hash_alg * alg,struct mem_range hash)296 static int incfs_build_merkle_tree(struct file *f, struct data_file *df,
297 			     struct backing_file_context *bfc,
298 			     struct mtree *hash_tree, loff_t hash_offset,
299 			     struct incfs_hash_alg *alg, struct mem_range hash)
300 {
301 	int error = 0;
302 	int limit, lvl, i, result;
303 	struct mem_range buf = {.len = INCFS_DATA_FILE_BLOCK_SIZE};
304 	struct mem_range tmp = {.len = 2 * INCFS_DATA_FILE_BLOCK_SIZE};
305 
306 	buf.data = (u8 *)__get_free_pages(GFP_NOFS, get_order(buf.len));
307 	tmp.data = (u8 *)__get_free_pages(GFP_NOFS, get_order(tmp.len));
308 	if (!buf.data || !tmp.data) {
309 		error = -ENOMEM;
310 		goto out;
311 	}
312 
313 	/*
314 	 * lvl - 1 is the level we are reading, lvl the level we are writing
315 	 * lvl == -1 means actual blocks
316 	 * lvl == hash_tree->depth means root hash
317 	 */
318 	limit = df->df_data_block_count;
319 	for (lvl = 0; lvl <= hash_tree->depth; lvl++) {
320 		for (i = 0; i < limit; ++i) {
321 			loff_t hash_level_offset;
322 			struct mem_range partial_buf = buf;
323 
324 			if (lvl == 0)
325 				result = incfs_read_data_file_block(partial_buf,
326 						f, i, tmp, NULL, NULL);
327 			else {
328 				hash_level_offset = hash_offset +
329 				       hash_tree->hash_level_suboffset[lvl - 1];
330 
331 				result = incfs_kread(bfc, partial_buf.data,
332 						partial_buf.len,
333 						hash_level_offset + i *
334 						INCFS_DATA_FILE_BLOCK_SIZE);
335 			}
336 
337 			if (result < 0) {
338 				error = result;
339 				goto out;
340 			}
341 
342 			partial_buf.len = result;
343 			error = incfs_calc_digest(alg, partial_buf, hash);
344 			if (error)
345 				goto out;
346 
347 			/*
348 			 * last level - only one hash to take and it is stored
349 			 * in the incfs signature record
350 			 */
351 			if (lvl == hash_tree->depth)
352 				break;
353 
354 			hash_level_offset = hash_offset +
355 				hash_tree->hash_level_suboffset[lvl];
356 
357 			result = incfs_kwrite(bfc, hash.data, hash.len,
358 					hash_level_offset + hash.len * i);
359 
360 			if (result < 0) {
361 				error = result;
362 				goto out;
363 			}
364 
365 			if (result != hash.len) {
366 				error = -EIO;
367 				goto out;
368 			}
369 		}
370 		limit = DIV_ROUND_UP(limit,
371 				     INCFS_DATA_FILE_BLOCK_SIZE / hash.len);
372 	}
373 
374 out:
375 	free_pages((unsigned long)tmp.data, get_order(tmp.len));
376 	free_pages((unsigned long)buf.data, get_order(buf.len));
377 	return error;
378 }
379 
380 /*
381  * incfs files have a signature record that is separate from the
382  * verity_signature record. The signature record does not actually contain a
383  * signature, rather it contains the size/offset of the hash tree, and a binary
384  * blob which contains the root hash and potentially a signature.
385  *
386  * If the file was created with a signature record, then this function simply
387  * returns.
388  *
389  * Otherwise it will create a signature record with a minimal binary blob as
390  * defined by the structure below, create space for the hash tree and then
391  * populate it using incfs_build_merkle_tree
392  */
incfs_add_signature_record(struct file * f)393 static int incfs_add_signature_record(struct file *f)
394 {
395 	/* See incfs_parse_signature */
396 	struct {
397 		__le32 version;
398 		__le32 size_of_hash_info_section;
399 		struct {
400 			__le32 hash_algorithm;
401 			u8 log2_blocksize;
402 			__le32 salt_size;
403 			u8 salt[0];
404 			__le32 hash_size;
405 			u8 root_hash[32];
406 		} __packed hash_section;
407 		__le32 size_of_signing_info_section;
408 		u8 signing_info_section[0];
409 	} __packed sig = {
410 		.version = cpu_to_le32(INCFS_SIGNATURE_VERSION),
411 		.size_of_hash_info_section =
412 			cpu_to_le32(sizeof(sig.hash_section)),
413 		.hash_section = {
414 			.hash_algorithm = cpu_to_le32(INCFS_HASH_TREE_SHA256),
415 			.log2_blocksize = ilog2(INCFS_DATA_FILE_BLOCK_SIZE),
416 			.hash_size = cpu_to_le32(SHA256_DIGEST_SIZE),
417 		},
418 	};
419 
420 	struct data_file *df = get_incfs_data_file(f);
421 	struct mtree *hash_tree = NULL;
422 	struct backing_file_context *bfc;
423 	int error;
424 	loff_t hash_offset, sig_offset;
425 	struct incfs_hash_alg *alg = incfs_get_hash_alg(INCFS_HASH_TREE_SHA256);
426 	u8 hash_buf[INCFS_MAX_HASH_SIZE];
427 	int hash_size = alg->digest_size;
428 	struct mem_range hash = range(hash_buf, hash_size);
429 	int result;
430 	struct incfs_df_signature *signature = NULL;
431 
432 	if (!df)
433 		return -EINVAL;
434 
435 	if (df->df_header_flags & INCFS_FILE_MAPPED)
436 		return -EINVAL;
437 
438 	/* Already signed? */
439 	if (df->df_signature && df->df_hash_tree)
440 		return 0;
441 
442 	if (df->df_signature || df->df_hash_tree)
443 		return -EFSCORRUPTED;
444 
445 	/* Add signature metadata record to file */
446 	hash_tree = incfs_alloc_mtree(range((u8 *)&sig, sizeof(sig)),
447 				      df->df_data_block_count);
448 	if (IS_ERR(hash_tree))
449 		return PTR_ERR(hash_tree);
450 
451 	bfc = df->df_backing_file_context;
452 	if (!bfc) {
453 		error = -EFSCORRUPTED;
454 		goto out;
455 	}
456 
457 	error = mutex_lock_interruptible(&bfc->bc_mutex);
458 	if (error)
459 		goto out;
460 
461 	error = incfs_write_signature_to_backing_file(bfc,
462 				range((u8 *)&sig, sizeof(sig)),
463 				hash_tree->hash_tree_area_size,
464 				&hash_offset, &sig_offset);
465 	mutex_unlock(&bfc->bc_mutex);
466 	if (error)
467 		goto out;
468 
469 	/* Populate merkle tree */
470 	error = incfs_build_merkle_tree(f, df, bfc, hash_tree, hash_offset, alg,
471 				  hash);
472 	if (error)
473 		goto out;
474 
475 	/* Update signature metadata record */
476 	memcpy(sig.hash_section.root_hash, hash.data, alg->digest_size);
477 	result = incfs_kwrite(bfc, &sig, sizeof(sig), sig_offset);
478 	if (result < 0) {
479 		error = result;
480 		goto out;
481 	}
482 
483 	if (result != sizeof(sig)) {
484 		error = -EIO;
485 		goto out;
486 	}
487 
488 	/* Update in-memory records */
489 	memcpy(hash_tree->root_hash, hash.data, alg->digest_size);
490 	signature = kzalloc(sizeof(*signature), GFP_NOFS);
491 	if (!signature) {
492 		error = -ENOMEM;
493 		goto out;
494 	}
495 	*signature = (struct incfs_df_signature) {
496 		.hash_offset = hash_offset,
497 		.hash_size = hash_tree->hash_tree_area_size,
498 		.sig_offset = sig_offset,
499 		.sig_size = sizeof(sig),
500 	};
501 	df->df_signature = signature;
502 	signature = NULL;
503 
504 	/*
505 	 * Use memory barrier to prevent readpage seeing the hash tree until
506 	 * it's fully there
507 	 */
508 	smp_store_release(&df->df_hash_tree, hash_tree);
509 	hash_tree = NULL;
510 
511 out:
512 	kfree(signature);
513 	kfree(hash_tree);
514 	return error;
515 }
516 
incfs_enable_verity(struct file * filp,const struct fsverity_enable_arg * arg)517 static int incfs_enable_verity(struct file *filp,
518 			 const struct fsverity_enable_arg *arg)
519 {
520 	struct inode *inode = file_inode(filp);
521 	struct data_file *df = get_incfs_data_file(filp);
522 	u8 *signature = NULL;
523 	struct mem_range verity_file_digest = range(NULL, 0);
524 	int err;
525 
526 	if (!df)
527 		return -EFSCORRUPTED;
528 
529 	err = mutex_lock_interruptible(&df->df_enable_verity);
530 	if (err)
531 		return err;
532 
533 	if (IS_VERITY(inode)) {
534 		err = -EEXIST;
535 		goto out;
536 	}
537 
538 	err = incfs_add_signature_record(filp);
539 	if (err)
540 		goto out;
541 
542 	/* Get the signature if the user provided one */
543 	if (arg->sig_size) {
544 		signature = memdup_user(u64_to_user_ptr(arg->sig_ptr),
545 					arg->sig_size);
546 		if (IS_ERR(signature)) {
547 			err = PTR_ERR(signature);
548 			signature = NULL;
549 			goto out;
550 		}
551 	}
552 
553 	verity_file_digest = incfs_calc_verity_digest(inode, filp, signature,
554 					arg->sig_size, arg->hash_algorithm);
555 	if (IS_ERR(verity_file_digest.data)) {
556 		err = PTR_ERR(verity_file_digest.data);
557 		verity_file_digest.data = NULL;
558 		goto out;
559 	}
560 
561 	err = incfs_end_enable_verity(filp, signature, arg->sig_size);
562 	if (err)
563 		goto out;
564 
565 	/* Successfully enabled verity */
566 	incfs_set_verity_digest(inode, verity_file_digest);
567 	verity_file_digest.data = NULL;
568 out:
569 	mutex_unlock(&df->df_enable_verity);
570 	kfree(signature);
571 	kfree(verity_file_digest.data);
572 	if (err)
573 		pr_err("%s failed with err %d\n", __func__, err);
574 	return err;
575 }
576 
incfs_ioctl_enable_verity(struct file * filp,const void __user * uarg)577 int incfs_ioctl_enable_verity(struct file *filp, const void __user *uarg)
578 {
579 	struct inode *inode = file_inode(filp);
580 	struct fsverity_enable_arg arg;
581 
582 	if (copy_from_user(&arg, uarg, sizeof(arg)))
583 		return -EFAULT;
584 
585 	if (arg.version != 1)
586 		return -EINVAL;
587 
588 	if (arg.__reserved1 ||
589 	    memchr_inv(arg.__reserved2, 0, sizeof(arg.__reserved2)))
590 		return -EINVAL;
591 
592 	if (arg.hash_algorithm != FS_VERITY_HASH_ALG_SHA256)
593 		return -EINVAL;
594 
595 	if (arg.block_size != PAGE_SIZE)
596 		return -EINVAL;
597 
598 	if (arg.salt_size)
599 		return -EINVAL;
600 
601 	if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE)
602 		return -EMSGSIZE;
603 
604 	if (S_ISDIR(inode->i_mode))
605 		return -EISDIR;
606 
607 	if (!S_ISREG(inode->i_mode))
608 		return -EINVAL;
609 
610 	return incfs_enable_verity(filp, &arg);
611 }
612 
incfs_get_verity_signature(struct file * filp,size_t * sig_size)613 static u8 *incfs_get_verity_signature(struct file *filp, size_t *sig_size)
614 {
615 	struct data_file *df = get_incfs_data_file(filp);
616 	struct incfs_df_verity_signature *vs;
617 	u8 *signature;
618 	int res;
619 
620 	if (!df || !df->df_backing_file_context)
621 		return ERR_PTR(-EFSCORRUPTED);
622 
623 	vs = df->df_verity_signature;
624 	if (!vs) {
625 		*sig_size = 0;
626 		return NULL;
627 	}
628 
629 	if (!vs->size) {
630 		*sig_size = 0;
631 		return ERR_PTR(-EFSCORRUPTED);
632 	}
633 
634 	signature = kzalloc(vs->size, GFP_KERNEL);
635 	if (!signature)
636 		return ERR_PTR(-ENOMEM);
637 
638 	res = incfs_kread(df->df_backing_file_context,
639 			  signature, vs->size, vs->offset);
640 
641 	if (res < 0)
642 		goto err_out;
643 
644 	if (res != vs->size) {
645 		res = -EINVAL;
646 		goto err_out;
647 	}
648 
649 	*sig_size = vs->size;
650 	return signature;
651 
652 err_out:
653 	kfree(signature);
654 	return ERR_PTR(res);
655 }
656 
657 /* Ensure data_file->df_verity_file_digest is populated */
ensure_verity_info(struct inode * inode,struct file * filp)658 static int ensure_verity_info(struct inode *inode, struct file *filp)
659 {
660 	struct mem_range verity_file_digest;
661 	u8 *signature = NULL;
662 	size_t sig_size;
663 	int err = 0;
664 
665 	/* See if this file's verity file digest is already cached */
666 	verity_file_digest = incfs_get_verity_digest(inode);
667 	if (verity_file_digest.data)
668 		return 0;
669 
670 	signature = incfs_get_verity_signature(filp, &sig_size);
671 	if (IS_ERR(signature))
672 		return PTR_ERR(signature);
673 
674 	verity_file_digest = incfs_calc_verity_digest(inode, filp, signature,
675 						     sig_size,
676 						     FS_VERITY_HASH_ALG_SHA256);
677 	if (IS_ERR(verity_file_digest.data)) {
678 		err = PTR_ERR(verity_file_digest.data);
679 		goto out;
680 	}
681 
682 	incfs_set_verity_digest(inode, verity_file_digest);
683 
684 out:
685 	kfree(signature);
686 	return err;
687 }
688 
689 /**
690  * incfs_fsverity_file_open() - prepare to open a file that may be
691  * verity-enabled
692  * @inode: the inode being opened
693  * @filp: the struct file being set up
694  *
695  * When opening a verity file, set up data_file->df_verity_file_digest if not
696  * already done. Note that incfs does not allow opening for writing, so there is
697  * no need for that check.
698  *
699  * Return: 0 on success, -errno on failure
700  */
incfs_fsverity_file_open(struct inode * inode,struct file * filp)701 int incfs_fsverity_file_open(struct inode *inode, struct file *filp)
702 {
703 	if (IS_VERITY(inode))
704 		return ensure_verity_info(inode, filp);
705 
706 	return 0;
707 }
708 
incfs_ioctl_measure_verity(struct file * filp,void __user * _uarg)709 int incfs_ioctl_measure_verity(struct file *filp, void __user *_uarg)
710 {
711 	struct inode *inode = file_inode(filp);
712 	struct mem_range verity_file_digest = incfs_get_verity_digest(inode);
713 	struct fsverity_digest __user *uarg = _uarg;
714 	struct fsverity_digest arg;
715 
716 	if (!verity_file_digest.data || !verity_file_digest.len)
717 		return -ENODATA; /* not a verity file */
718 
719 	/*
720 	 * The user specifies the digest_size their buffer has space for; we can
721 	 * return the digest if it fits in the available space.  We write back
722 	 * the actual size, which may be shorter than the user-specified size.
723 	 */
724 
725 	if (get_user(arg.digest_size, &uarg->digest_size))
726 		return -EFAULT;
727 	if (arg.digest_size < verity_file_digest.len)
728 		return -EOVERFLOW;
729 
730 	memset(&arg, 0, sizeof(arg));
731 	arg.digest_algorithm = FS_VERITY_HASH_ALG_SHA256;
732 	arg.digest_size = verity_file_digest.len;
733 
734 	if (copy_to_user(uarg, &arg, sizeof(arg)))
735 		return -EFAULT;
736 
737 	if (copy_to_user(uarg->digest, verity_file_digest.data,
738 			 verity_file_digest.len))
739 		return -EFAULT;
740 
741 	return 0;
742 }
743 
incfs_read_merkle_tree(struct file * filp,void __user * buf,u64 start_offset,int length)744 static int incfs_read_merkle_tree(struct file *filp, void __user *buf,
745 				  u64 start_offset, int length)
746 {
747 	struct mem_range tmp_buf;
748 	size_t offset;
749 	int retval = 0;
750 	int err = 0;
751 	struct data_file *df = get_incfs_data_file(filp);
752 
753 	if (!df)
754 		return -EINVAL;
755 
756 	tmp_buf = (struct mem_range) {
757 		.data = kzalloc(INCFS_DATA_FILE_BLOCK_SIZE, GFP_NOFS),
758 		.len = INCFS_DATA_FILE_BLOCK_SIZE,
759 	};
760 	if (!tmp_buf.data)
761 		return -ENOMEM;
762 
763 	for (offset = start_offset; offset < start_offset + length;
764 	     offset += tmp_buf.len) {
765 		err = incfs_read_merkle_tree_blocks(tmp_buf, df, offset);
766 
767 		if (err < 0)
768 			break;
769 
770 		if (err != tmp_buf.len)
771 			break;
772 
773 		if (copy_to_user(buf, tmp_buf.data, tmp_buf.len))
774 			break;
775 
776 		buf += tmp_buf.len;
777 		retval += tmp_buf.len;
778 	}
779 
780 	kfree(tmp_buf.data);
781 	return retval ? retval : err;
782 }
783 
incfs_read_descriptor(struct file * filp,void __user * buf,u64 offset,int length)784 static int incfs_read_descriptor(struct file *filp,
785 				 void __user *buf, u64 offset, int length)
786 {
787 	int err;
788 	struct fsverity_descriptor *desc = incfs_get_fsverity_descriptor(filp,
789 						FS_VERITY_HASH_ALG_SHA256);
790 
791 	if (IS_ERR(desc))
792 		return PTR_ERR(desc);
793 	length = min_t(u64, length, sizeof(*desc));
794 	err = copy_to_user(buf, desc, length);
795 	kfree(desc);
796 	return err ? err : length;
797 }
798 
incfs_read_signature(struct file * filp,void __user * buf,u64 offset,int length)799 static int incfs_read_signature(struct file *filp,
800 				void __user *buf, u64 offset, int length)
801 {
802 	size_t sig_size;
803 	static u8 *signature;
804 	int err;
805 
806 	signature = incfs_get_verity_signature(filp, &sig_size);
807 	if (IS_ERR(signature))
808 		return PTR_ERR(signature);
809 
810 	if (!signature)
811 		return -ENODATA;
812 
813 	length = min_t(u64, length, sig_size);
814 	err = copy_to_user(buf, signature, length);
815 	kfree(signature);
816 	return err ? err : length;
817 }
818 
incfs_ioctl_read_verity_metadata(struct file * filp,const void __user * uarg)819 int incfs_ioctl_read_verity_metadata(struct file *filp,
820 				     const void __user *uarg)
821 {
822 	struct fsverity_read_metadata_arg arg;
823 	int length;
824 	void __user *buf;
825 
826 	if (copy_from_user(&arg, uarg, sizeof(arg)))
827 		return -EFAULT;
828 
829 	if (arg.__reserved)
830 		return -EINVAL;
831 
832 	/* offset + length must not overflow. */
833 	if (arg.offset + arg.length < arg.offset)
834 		return -EINVAL;
835 
836 	/* Ensure that the return value will fit in INT_MAX. */
837 	length = min_t(u64, arg.length, INT_MAX);
838 
839 	buf = u64_to_user_ptr(arg.buf_ptr);
840 
841 	switch (arg.metadata_type) {
842 	case FS_VERITY_METADATA_TYPE_MERKLE_TREE:
843 		return incfs_read_merkle_tree(filp, buf, arg.offset, length);
844 	case FS_VERITY_METADATA_TYPE_DESCRIPTOR:
845 		return incfs_read_descriptor(filp, buf, arg.offset, length);
846 	case FS_VERITY_METADATA_TYPE_SIGNATURE:
847 		return incfs_read_signature(filp, buf, arg.offset, length);
848 	default:
849 		return -EINVAL;
850 	}
851 }
852