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