xref: /OK3568_Linux_fs/kernel/fs/f2fs/verity.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * fs/f2fs/verity.c: fs-verity support for f2fs
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2019 Google LLC
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  * Implementation of fsverity_operations for f2fs.
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * Like ext4, f2fs stores the verity metadata (Merkle tree and
12*4882a593Smuzhiyun  * fsverity_descriptor) past the end of the file, starting at the first 64K
13*4882a593Smuzhiyun  * boundary beyond i_size.  This approach works because (a) verity files are
14*4882a593Smuzhiyun  * readonly, and (b) pages fully beyond i_size aren't visible to userspace but
15*4882a593Smuzhiyun  * can be read/written internally by f2fs with only some relatively small
16*4882a593Smuzhiyun  * changes to f2fs.  Extended attributes cannot be used because (a) f2fs limits
17*4882a593Smuzhiyun  * the total size of an inode's xattr entries to 4096 bytes, which wouldn't be
18*4882a593Smuzhiyun  * enough for even a single Merkle tree block, and (b) f2fs encryption doesn't
19*4882a593Smuzhiyun  * encrypt xattrs, yet the verity metadata *must* be encrypted when the file is
20*4882a593Smuzhiyun  * because it contains hashes of the plaintext data.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * Using a 64K boundary rather than a 4K one keeps things ready for
23*4882a593Smuzhiyun  * architectures with 64K pages, and it doesn't necessarily waste space on-disk
24*4882a593Smuzhiyun  * since there can be a hole between i_size and the start of the Merkle tree.
25*4882a593Smuzhiyun  */
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include <linux/f2fs_fs.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #include "f2fs.h"
30*4882a593Smuzhiyun #include "xattr.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define F2FS_VERIFY_VER	(1)
33*4882a593Smuzhiyun 
f2fs_verity_metadata_pos(const struct inode * inode)34*4882a593Smuzhiyun static inline loff_t f2fs_verity_metadata_pos(const struct inode *inode)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	return round_up(inode->i_size, 65536);
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /*
40*4882a593Smuzhiyun  * Read some verity metadata from the inode.  __vfs_read() can't be used because
41*4882a593Smuzhiyun  * we need to read beyond i_size.
42*4882a593Smuzhiyun  */
pagecache_read(struct inode * inode,void * buf,size_t count,loff_t pos)43*4882a593Smuzhiyun static int pagecache_read(struct inode *inode, void *buf, size_t count,
44*4882a593Smuzhiyun 			  loff_t pos)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	while (count) {
47*4882a593Smuzhiyun 		size_t n = min_t(size_t, count,
48*4882a593Smuzhiyun 				 PAGE_SIZE - offset_in_page(pos));
49*4882a593Smuzhiyun 		struct page *page;
50*4882a593Smuzhiyun 		void *addr;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 		page = read_mapping_page(inode->i_mapping, pos >> PAGE_SHIFT,
53*4882a593Smuzhiyun 					 NULL);
54*4882a593Smuzhiyun 		if (IS_ERR(page))
55*4882a593Smuzhiyun 			return PTR_ERR(page);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 		addr = kmap_atomic(page);
58*4882a593Smuzhiyun 		memcpy(buf, addr + offset_in_page(pos), n);
59*4882a593Smuzhiyun 		kunmap_atomic(addr);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 		put_page(page);
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 		buf += n;
64*4882a593Smuzhiyun 		pos += n;
65*4882a593Smuzhiyun 		count -= n;
66*4882a593Smuzhiyun 	}
67*4882a593Smuzhiyun 	return 0;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /*
71*4882a593Smuzhiyun  * Write some verity metadata to the inode for FS_IOC_ENABLE_VERITY.
72*4882a593Smuzhiyun  * kernel_write() can't be used because the file descriptor is readonly.
73*4882a593Smuzhiyun  */
pagecache_write(struct inode * inode,const void * buf,size_t count,loff_t pos)74*4882a593Smuzhiyun static int pagecache_write(struct inode *inode, const void *buf, size_t count,
75*4882a593Smuzhiyun 			   loff_t pos)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun 	if (pos + count > inode->i_sb->s_maxbytes)
78*4882a593Smuzhiyun 		return -EFBIG;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	while (count) {
81*4882a593Smuzhiyun 		size_t n = min_t(size_t, count,
82*4882a593Smuzhiyun 				 PAGE_SIZE - offset_in_page(pos));
83*4882a593Smuzhiyun 		struct page *page;
84*4882a593Smuzhiyun 		void *fsdata;
85*4882a593Smuzhiyun 		void *addr;
86*4882a593Smuzhiyun 		int res;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 		res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0,
89*4882a593Smuzhiyun 					    &page, &fsdata);
90*4882a593Smuzhiyun 		if (res)
91*4882a593Smuzhiyun 			return res;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 		addr = kmap_atomic(page);
94*4882a593Smuzhiyun 		memcpy(addr + offset_in_page(pos), buf, n);
95*4882a593Smuzhiyun 		kunmap_atomic(addr);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 		res = pagecache_write_end(NULL, inode->i_mapping, pos, n, n,
98*4882a593Smuzhiyun 					  page, fsdata);
99*4882a593Smuzhiyun 		if (res < 0)
100*4882a593Smuzhiyun 			return res;
101*4882a593Smuzhiyun 		if (res != n)
102*4882a593Smuzhiyun 			return -EIO;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 		buf += n;
105*4882a593Smuzhiyun 		pos += n;
106*4882a593Smuzhiyun 		count -= n;
107*4882a593Smuzhiyun 	}
108*4882a593Smuzhiyun 	return 0;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /*
112*4882a593Smuzhiyun  * Format of f2fs verity xattr.  This points to the location of the verity
113*4882a593Smuzhiyun  * descriptor within the file data rather than containing it directly because
114*4882a593Smuzhiyun  * the verity descriptor *must* be encrypted when f2fs encryption is used.  But,
115*4882a593Smuzhiyun  * f2fs encryption does not encrypt xattrs.
116*4882a593Smuzhiyun  */
117*4882a593Smuzhiyun struct fsverity_descriptor_location {
118*4882a593Smuzhiyun 	__le32 version;
119*4882a593Smuzhiyun 	__le32 size;
120*4882a593Smuzhiyun 	__le64 pos;
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun 
f2fs_begin_enable_verity(struct file * filp)123*4882a593Smuzhiyun static int f2fs_begin_enable_verity(struct file *filp)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	struct inode *inode = file_inode(filp);
126*4882a593Smuzhiyun 	int err;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	if (f2fs_verity_in_progress(inode))
129*4882a593Smuzhiyun 		return -EBUSY;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode))
132*4882a593Smuzhiyun 		return -EOPNOTSUPP;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	/*
135*4882a593Smuzhiyun 	 * Since the file was opened readonly, we have to initialize the quotas
136*4882a593Smuzhiyun 	 * here and not rely on ->open() doing it.  This must be done before
137*4882a593Smuzhiyun 	 * evicting the inline data.
138*4882a593Smuzhiyun 	 */
139*4882a593Smuzhiyun 	err = dquot_initialize(inode);
140*4882a593Smuzhiyun 	if (err)
141*4882a593Smuzhiyun 		return err;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	err = f2fs_convert_inline_inode(inode);
144*4882a593Smuzhiyun 	if (err)
145*4882a593Smuzhiyun 		return err;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	set_inode_flag(inode, FI_VERITY_IN_PROGRESS);
148*4882a593Smuzhiyun 	return 0;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
f2fs_end_enable_verity(struct file * filp,const void * desc,size_t desc_size,u64 merkle_tree_size)151*4882a593Smuzhiyun static int f2fs_end_enable_verity(struct file *filp, const void *desc,
152*4882a593Smuzhiyun 				  size_t desc_size, u64 merkle_tree_size)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	struct inode *inode = file_inode(filp);
155*4882a593Smuzhiyun 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
156*4882a593Smuzhiyun 	u64 desc_pos = f2fs_verity_metadata_pos(inode) + merkle_tree_size;
157*4882a593Smuzhiyun 	struct fsverity_descriptor_location dloc = {
158*4882a593Smuzhiyun 		.version = cpu_to_le32(F2FS_VERIFY_VER),
159*4882a593Smuzhiyun 		.size = cpu_to_le32(desc_size),
160*4882a593Smuzhiyun 		.pos = cpu_to_le64(desc_pos),
161*4882a593Smuzhiyun 	};
162*4882a593Smuzhiyun 	int err = 0, err2 = 0;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	/*
165*4882a593Smuzhiyun 	 * If an error already occurred (which fs/verity/ signals by passing
166*4882a593Smuzhiyun 	 * desc == NULL), then only clean-up is needed.
167*4882a593Smuzhiyun 	 */
168*4882a593Smuzhiyun 	if (desc == NULL)
169*4882a593Smuzhiyun 		goto cleanup;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	/* Append the verity descriptor. */
172*4882a593Smuzhiyun 	err = pagecache_write(inode, desc, desc_size, desc_pos);
173*4882a593Smuzhiyun 	if (err)
174*4882a593Smuzhiyun 		goto cleanup;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	/*
177*4882a593Smuzhiyun 	 * Write all pages (both data and verity metadata).  Note that this must
178*4882a593Smuzhiyun 	 * happen before clearing FI_VERITY_IN_PROGRESS; otherwise pages beyond
179*4882a593Smuzhiyun 	 * i_size won't be written properly.  For crash consistency, this also
180*4882a593Smuzhiyun 	 * must happen before the verity inode flag gets persisted.
181*4882a593Smuzhiyun 	 */
182*4882a593Smuzhiyun 	err = filemap_write_and_wait(inode->i_mapping);
183*4882a593Smuzhiyun 	if (err)
184*4882a593Smuzhiyun 		goto cleanup;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	/* Set the verity xattr. */
187*4882a593Smuzhiyun 	err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY,
188*4882a593Smuzhiyun 			    F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc),
189*4882a593Smuzhiyun 			    NULL, XATTR_CREATE);
190*4882a593Smuzhiyun 	if (err)
191*4882a593Smuzhiyun 		goto cleanup;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* Finally, set the verity inode flag. */
194*4882a593Smuzhiyun 	file_set_verity(inode);
195*4882a593Smuzhiyun 	f2fs_set_inode_flags(inode);
196*4882a593Smuzhiyun 	f2fs_mark_inode_dirty_sync(inode, true);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
199*4882a593Smuzhiyun 	return 0;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun cleanup:
202*4882a593Smuzhiyun 	/*
203*4882a593Smuzhiyun 	 * Verity failed to be enabled, so clean up by truncating any verity
204*4882a593Smuzhiyun 	 * metadata that was written beyond i_size (both from cache and from
205*4882a593Smuzhiyun 	 * disk) and clearing FI_VERITY_IN_PROGRESS.
206*4882a593Smuzhiyun 	 *
207*4882a593Smuzhiyun 	 * Taking i_gc_rwsem[WRITE] is needed to stop f2fs garbage collection
208*4882a593Smuzhiyun 	 * from re-instantiating cached pages we are truncating (since unlike
209*4882a593Smuzhiyun 	 * normal file accesses, garbage collection isn't limited by i_size).
210*4882a593Smuzhiyun 	 */
211*4882a593Smuzhiyun 	f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
212*4882a593Smuzhiyun 	truncate_inode_pages(inode->i_mapping, inode->i_size);
213*4882a593Smuzhiyun 	err2 = f2fs_truncate(inode);
214*4882a593Smuzhiyun 	if (err2) {
215*4882a593Smuzhiyun 		f2fs_err(sbi, "Truncating verity metadata failed (errno=%d)",
216*4882a593Smuzhiyun 			 err2);
217*4882a593Smuzhiyun 		set_sbi_flag(sbi, SBI_NEED_FSCK);
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 	f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
220*4882a593Smuzhiyun 	clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
221*4882a593Smuzhiyun 	return err ?: err2;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
f2fs_get_verity_descriptor(struct inode * inode,void * buf,size_t buf_size)224*4882a593Smuzhiyun static int f2fs_get_verity_descriptor(struct inode *inode, void *buf,
225*4882a593Smuzhiyun 				      size_t buf_size)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun 	struct fsverity_descriptor_location dloc;
228*4882a593Smuzhiyun 	int res;
229*4882a593Smuzhiyun 	u32 size;
230*4882a593Smuzhiyun 	u64 pos;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	/* Get the descriptor location */
233*4882a593Smuzhiyun 	res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_VERITY,
234*4882a593Smuzhiyun 			    F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), NULL);
235*4882a593Smuzhiyun 	if (res < 0 && res != -ERANGE)
236*4882a593Smuzhiyun 		return res;
237*4882a593Smuzhiyun 	if (res != sizeof(dloc) || dloc.version != cpu_to_le32(F2FS_VERIFY_VER)) {
238*4882a593Smuzhiyun 		f2fs_warn(F2FS_I_SB(inode), "unknown verity xattr format");
239*4882a593Smuzhiyun 		return -EINVAL;
240*4882a593Smuzhiyun 	}
241*4882a593Smuzhiyun 	size = le32_to_cpu(dloc.size);
242*4882a593Smuzhiyun 	pos = le64_to_cpu(dloc.pos);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	/* Get the descriptor */
245*4882a593Smuzhiyun 	if (pos + size < pos || pos + size > inode->i_sb->s_maxbytes ||
246*4882a593Smuzhiyun 	    pos < f2fs_verity_metadata_pos(inode) || size > INT_MAX) {
247*4882a593Smuzhiyun 		f2fs_warn(F2FS_I_SB(inode), "invalid verity xattr");
248*4882a593Smuzhiyun 		return -EFSCORRUPTED;
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 	if (buf_size) {
251*4882a593Smuzhiyun 		if (size > buf_size)
252*4882a593Smuzhiyun 			return -ERANGE;
253*4882a593Smuzhiyun 		res = pagecache_read(inode, buf, size, pos);
254*4882a593Smuzhiyun 		if (res)
255*4882a593Smuzhiyun 			return res;
256*4882a593Smuzhiyun 	}
257*4882a593Smuzhiyun 	return size;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
f2fs_read_merkle_tree_page(struct inode * inode,pgoff_t index,unsigned long num_ra_pages)260*4882a593Smuzhiyun static struct page *f2fs_read_merkle_tree_page(struct inode *inode,
261*4882a593Smuzhiyun 					       pgoff_t index,
262*4882a593Smuzhiyun 					       unsigned long num_ra_pages)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	struct page *page;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	index += f2fs_verity_metadata_pos(inode) >> PAGE_SHIFT;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED);
269*4882a593Smuzhiyun 	if (!page || !PageUptodate(page)) {
270*4882a593Smuzhiyun 		DEFINE_READAHEAD(ractl, NULL, inode->i_mapping, index);
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 		if (page)
273*4882a593Smuzhiyun 			put_page(page);
274*4882a593Smuzhiyun 		else if (num_ra_pages > 1)
275*4882a593Smuzhiyun 			page_cache_ra_unbounded(&ractl, num_ra_pages, 0);
276*4882a593Smuzhiyun 		page = read_mapping_page(inode->i_mapping, index, NULL);
277*4882a593Smuzhiyun 	}
278*4882a593Smuzhiyun 	return page;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
f2fs_write_merkle_tree_block(struct inode * inode,const void * buf,u64 index,int log_blocksize)281*4882a593Smuzhiyun static int f2fs_write_merkle_tree_block(struct inode *inode, const void *buf,
282*4882a593Smuzhiyun 					u64 index, int log_blocksize)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	loff_t pos = f2fs_verity_metadata_pos(inode) + (index << log_blocksize);
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	return pagecache_write(inode, buf, 1 << log_blocksize, pos);
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun const struct fsverity_operations f2fs_verityops = {
290*4882a593Smuzhiyun 	.begin_enable_verity	= f2fs_begin_enable_verity,
291*4882a593Smuzhiyun 	.end_enable_verity	= f2fs_end_enable_verity,
292*4882a593Smuzhiyun 	.get_verity_descriptor	= f2fs_get_verity_descriptor,
293*4882a593Smuzhiyun 	.read_merkle_tree_page	= f2fs_read_merkle_tree_page,
294*4882a593Smuzhiyun 	.write_merkle_tree_block = f2fs_write_merkle_tree_block,
295*4882a593Smuzhiyun };
296