| 1 | |
| 2 | |
| 3 | * fs/ext4/verity.c: fs-verity support for ext4
|
| 4 | *
|
| 5 | * Copyright 2019 Google LLC
|
| 6 |
|
| 7 |
|
| 8 | |
| 9 | * Implementation of fsverity_operations for ext4.
|
| 10 | *
|
| 11 | * ext4 stores the verity metadata (Merkle tree and fsverity_descriptor) past
|
| 12 | * the end of the file, starting at the first 64K boundary beyond i_size. This
|
| 13 | * approach works because (a) verity files are readonly, and (b) pages fully
|
| 14 | * beyond i_size aren't visible to userspace but can be read/written internally
|
| 15 | * by ext4 with only some relatively small changes to ext4. This approach
|
| 16 | * avoids having to depend on the EA_INODE feature and on rearchitecturing
|
| 17 | * ext4's xattr support to support paging multi-gigabyte xattrs into memory, and
|
| 18 | * to support encrypting xattrs. Note that the verity metadata *must* be
|
| 19 | * encrypted when the file is, since it contains hashes of the plaintext data.
|
| 20 | *
|
| 21 | * Using a 64K boundary rather than a 4K one keeps things ready for
|
| 22 | * architectures with 64K pages, and it doesn't necessarily waste space on-disk
|
| 23 | * since there can be a hole between i_size and the start of the Merkle tree.
|
| 24 |
|
| 25 |
|
| 26 | #include <linux/quotaops.h>
|
| 27 |
|
| 28 | #include "ext4.h"
|
| 29 | #include "ext4_extents.h"
|
| 30 | #include "ext4_jbd2.h"
|
| 31 |
|
| 32 | static inline loff_t ext4_verity_metadata_pos(const struct inode *inode)
|
| 33 | {
|
| 34 | return round_up(inode->i_size, 65536);
|
| 35 | }
|
| 36 |
|
| 37 | |
| 38 | * Write some verity metadata to the inode for FS_IOC_ENABLE_VERITY.
|
| 39 | * kernel_write() can't be used because the file descriptor is readonly.
|
| 40 |
|
| 41 | static int pagecache_write(struct inode *inode, const void *buf, size_t count,
|
| 42 | loff_t pos)
|
| 43 | {
|
| 44 | struct address_space *mapping = inode->i_mapping;
|
| 45 | const struct address_space_operations *aops = mapping->a_ops;
|
| 46 |
|
| 47 | if (pos + count > inode->i_sb->s_maxbytes)
|
| 48 | return -EFBIG;
|
| 49 |
|
| 50 | while (count) {
|
| 51 | size_t n = min_t(size_t, count,
|
| 52 | PAGE_SIZE - offset_in_page(pos));
|
| 53 | struct folio *folio;
|
| 54 | void *fsdata = NULL;
|
| 55 | int res;
|
| 56 |
|
| 57 | res = aops->write_begin(NULL, mapping, pos, n, &folio, &fsdata);
|
| 58 | if (res)
|
| 59 | return res;
|
| 60 |
|
| 61 | memcpy_to_folio(folio, offset_in_folio(folio, pos), buf, n);
|
| 62 |
|
| 63 | res = aops->write_end(NULL, mapping, pos, n, n, folio, fsdata);
|
| 64 | if (res < 0)
|
| 65 | return res;
|
| 66 | if (res != n)
|
| 67 | return -EIO;
|
| 68 |
|
| 69 | buf += n;
|
| 70 | pos += n;
|
| 71 | count -= n;
|
| 72 | }
|
| 73 | return 0;
|
| 74 | }
|
| 75 |
|
| 76 | static int ext4_begin_enable_verity(struct file *filp)
|
| 77 | {
|
| 78 | struct inode *inode = file_inode(filp);
|
| 79 | const int credits = 2;
|
| 80 | handle_t *handle;
|
| 81 | int err;
|
| 82 |
|
| 83 | if (IS_DAX(inode) || ext4_test_inode_flag(inode, EXT4_INODE_DAX))
|
| 84 | return -EINVAL;
|
| 85 |
|
| 86 | if (ext4_verity_in_progress(inode))
|
| 87 | return -EBUSY;
|
| 88 |
|
| 89 | |
| 90 | * Since the file was opened readonly, we have to initialize the jbd
|
| 91 | * inode and quotas here and not rely on ->open() doing it. This must
|
| 92 | * be done before evicting the inline data.
|
| 93 |
|
| 94 |
|
| 95 | err = ext4_inode_attach_jinode(inode);
|
| 96 | if (err)
|
| 97 | return err;
|
| 98 |
|
| 99 | err = dquot_initialize(inode);
|
| 100 | if (err)
|
| 101 | return err;
|
| 102 |
|
| 103 | err = ext4_convert_inline_data(inode);
|
| 104 | if (err)
|
| 105 | return err;
|
| 106 |
|
| 107 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
|
| 108 | ext4_warning_inode(inode,
|
| 109 | "verity is only allowed on extent-based files");
|
| 110 | return -EOPNOTSUPP;
|
| 111 | }
|
| 112 |
|
| 113 | |
| 114 | * ext4 uses the last allocated block to find the verity descriptor, so
|
| 115 | * we must remove any other blocks past EOF which might confuse things.
|
| 116 |
|
| 117 | err = ext4_truncate(inode);
|
| 118 | if (err)
|
| 119 | return err;
|
| 120 |
|
| 121 | handle = ext4_journal_start(inode, EXT4_HT_INODE, credits);
|
| 122 | if (IS_ERR(handle))
|
| 123 | return PTR_ERR(handle);
|
| 124 |
|
| 125 | err = ext4_orphan_add(handle, inode);
|
| 126 | if (err == 0)
|
| 127 | ext4_set_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
|
| 128 |
|
| 129 | ext4_journal_stop(handle);
|
| 130 | return err;
|
| 131 | }
|
| 132 |
|
| 133 | |
| 134 | * ext4 stores the verity descriptor beginning on the next filesystem block
|
| 135 | * boundary after the Merkle tree. Then, the descriptor size is stored in the
|
| 136 | * last 4 bytes of the last allocated filesystem block --- which is either the
|
| 137 | * block in which the descriptor ends, or the next block after that if there
|
| 138 | * weren't at least 4 bytes remaining.
|
| 139 | *
|
| 140 | * We can't simply store the descriptor in an xattr because it *must* be
|
| 141 | * encrypted when ext4 encryption is used, but ext4 encryption doesn't encrypt
|
| 142 | * xattrs. Also, if the descriptor includes a large signature blob it may be
|
| 143 | * too large to store in an xattr without the EA_INODE feature.
|
| 144 |
|
| 145 | static int ext4_write_verity_descriptor(struct inode *inode, const void *desc,
|
| 146 | size_t desc_size, u64 merkle_tree_size)
|
| 147 | {
|
| 148 | const u64 desc_pos = round_up(ext4_verity_metadata_pos(inode) +
|
| 149 | merkle_tree_size, i_blocksize(inode));
|
| 150 | const u64 desc_end = desc_pos + desc_size;
|
| 151 | const __le32 desc_size_disk = cpu_to_le32(desc_size);
|
| 152 | const u64 desc_size_pos = round_up(desc_end + sizeof(desc_size_disk),
|
| 153 | i_blocksize(inode)) -
|
| 154 | sizeof(desc_size_disk);
|
| 155 | int err;
|
| 156 |
|
| 157 | err = pagecache_write(inode, desc, desc_size, desc_pos);
|
| 158 | if (err)
|
| 159 | return err;
|
| 160 |
|
| 161 | return pagecache_write(inode, &desc_size_disk, sizeof(desc_size_disk),
|
| 162 | desc_size_pos);
|
| 163 | }
|
| 164 |
|
| 165 | static int ext4_end_enable_verity(struct file *filp, const void *desc,
|
| 166 | size_t desc_size, u64 merkle_tree_size)
|
| 167 | {
|
| 168 | struct inode *inode = file_inode(filp);
|
| 169 | const int credits = 2;
|
| 170 | handle_t *handle;
|
| 171 | struct ext4_iloc iloc;
|
| 172 | int err = 0;
|
| 173 |
|
| 174 | |
| 175 | * If an error already occurred (which fs/verity/ signals by passing
|
| 176 | * desc == NULL), then only clean-up is needed.
|
| 177 |
|
| 178 | if (desc == NULL)
|
| 179 | goto cleanup;
|
| 180 |
|
| 181 |
|
| 182 | err = ext4_write_verity_descriptor(inode, desc, desc_size,
|
| 183 | merkle_tree_size);
|
| 184 | if (err)
|
| 185 | goto cleanup;
|
| 186 |
|
| 187 | |
| 188 | * Write all pages (both data and verity metadata). Note that this must
|
| 189 | * happen before clearing EXT4_STATE_VERITY_IN_PROGRESS; otherwise pages
|
| 190 | * beyond i_size won't be written properly. For crash consistency, this
|
| 191 | * also must happen before the verity inode flag gets persisted.
|
| 192 |
|
| 193 | err = filemap_write_and_wait(inode->i_mapping);
|
| 194 | if (err)
|
| 195 | goto cleanup;
|
| 196 |
|
| 197 | |
| 198 | * Finally, set the verity inode flag and remove the inode from the
|
| 199 | * orphan list (in a single transaction).
|
| 200 |
|
| 201 |
|
| 202 | handle = ext4_journal_start(inode, EXT4_HT_INODE, credits);
|
| 203 | if (IS_ERR(handle)) {
|
| 204 | err = PTR_ERR(handle);
|
| 205 | goto cleanup;
|
| 206 | }
|
| 207 |
|
| 208 | ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_VERITY, handle);
|
| 209 |
|
| 210 | err = ext4_orphan_del(handle, inode);
|
| 211 | if (err)
|
| 212 | goto stop_and_cleanup;
|
| 213 |
|
| 214 | err = ext4_reserve_inode_write(handle, inode, &iloc);
|
| 215 | if (err)
|
| 216 | goto stop_and_cleanup;
|
| 217 |
|
| 218 | ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
|
| 219 | ext4_set_inode_flags(inode, false);
|
| 220 | err = ext4_mark_iloc_dirty(handle, inode, &iloc);
|
| 221 | if (err)
|
| 222 | goto stop_and_cleanup;
|
| 223 |
|
| 224 | ext4_journal_stop(handle);
|
| 225 |
|
| 226 | ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
|
| 227 | return 0;
|
| 228 |
|
| 229 | stop_and_cleanup:
|
| 230 | ext4_journal_stop(handle);
|
| 231 | cleanup:
|
| 232 | |
| 233 | * Verity failed to be enabled, so clean up by truncating any verity
|
| 234 | * metadata that was written beyond i_size (both from cache and from
|
| 235 | * disk), removing the inode from the orphan list (if it wasn't done
|
| 236 | * already), and clearing EXT4_STATE_VERITY_IN_PROGRESS.
|
| 237 |
|
| 238 | truncate_inode_pages(inode->i_mapping, inode->i_size);
|
| 239 | ext4_truncate(inode);
|
| 240 | ext4_orphan_del(NULL, inode);
|
| 241 | ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
|
| 242 | return err;
|
| 243 | }
|
| 244 |
|
| 245 | static int ext4_get_verity_descriptor_location(struct inode *inode,
|
| 246 | size_t *desc_size_ret,
|
| 247 | u64 *desc_pos_ret)
|
| 248 | {
|
| 249 | struct ext4_ext_path *path;
|
| 250 | struct ext4_extent *last_extent;
|
| 251 | u32 end_lblk;
|
| 252 | u64 desc_size_pos;
|
| 253 | __le32 desc_size_disk;
|
| 254 | u32 desc_size;
|
| 255 | u64 desc_pos;
|
| 256 | int err;
|
| 257 |
|
| 258 | |
| 259 | * Descriptor size is in last 4 bytes of last allocated block.
|
| 260 | * See ext4_write_verity_descriptor().
|
| 261 |
|
| 262 |
|
| 263 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
|
| 264 | EXT4_ERROR_INODE(inode, "verity file doesn't use extents");
|
| 265 | return -EFSCORRUPTED;
|
| 266 | }
|
| 267 |
|
| 268 | path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, 0);
|
| 269 | if (IS_ERR(path))
|
| 270 | return PTR_ERR(path);
|
| 271 |
|
| 272 | last_extent = path[path->p_depth].p_ext;
|
| 273 | if (!last_extent) {
|
| 274 | EXT4_ERROR_INODE(inode, "verity file has no extents");
|
| 275 | ext4_free_ext_path(path);
|
| 276 | return -EFSCORRUPTED;
|
| 277 | }
|
| 278 |
|
| 279 | end_lblk = le32_to_cpu(last_extent->ee_block) +
|
| 280 | ext4_ext_get_actual_len(last_extent);
|
| 281 | desc_size_pos = EXT4_LBLK_TO_B(inode, end_lblk);
|
| 282 | ext4_free_ext_path(path);
|
| 283 |
|
| 284 | if (desc_size_pos < sizeof(desc_size_disk))
|
| 285 | goto bad;
|
| 286 | desc_size_pos -= sizeof(desc_size_disk);
|
| 287 |
|
| 288 | err = fsverity_pagecache_read(inode, &desc_size_disk,
|
| 289 | sizeof(desc_size_disk), desc_size_pos);
|
| 290 | if (err)
|
| 291 | return err;
|
| 292 | desc_size = le32_to_cpu(desc_size_disk);
|
| 293 |
|
| 294 | |
| 295 | * The descriptor is stored just before the desc_size_disk, but starting
|
| 296 | * on a filesystem block boundary.
|
| 297 |
|
| 298 |
|
| 299 | if (desc_size > INT_MAX || desc_size > desc_size_pos)
|
| 300 | goto bad;
|
| 301 |
|
| 302 | desc_pos = round_down(desc_size_pos - desc_size, i_blocksize(inode));
|
| 303 | if (desc_pos < ext4_verity_metadata_pos(inode))
|
| 304 | goto bad;
|
| 305 |
|
| 306 | *desc_size_ret = desc_size;
|
| 307 | *desc_pos_ret = desc_pos;
|
| 308 | return 0;
|
| 309 |
|
| 310 | bad:
|
| 311 | EXT4_ERROR_INODE(inode, "verity file corrupted; can't find descriptor");
|
| 312 | return -EFSCORRUPTED;
|
| 313 | }
|
| 314 |
|
| 315 | static int ext4_get_verity_descriptor(struct inode *inode, void *buf,
|
| 316 | size_t buf_size)
|
| 317 | {
|
| 318 | size_t desc_size = 0;
|
| 319 | u64 desc_pos = 0;
|
| 320 | int err;
|
| 321 |
|
| 322 | err = ext4_get_verity_descriptor_location(inode, &desc_size, &desc_pos);
|
| 323 | if (err)
|
| 324 | return err;
|
| 325 |
|
| 326 | if (buf_size) {
|
| 327 | if (desc_size > buf_size)
|
| 328 | return -ERANGE;
|
| 329 | err = fsverity_pagecache_read(inode, buf, desc_size, desc_pos);
|
| 330 | if (err)
|
| 331 | return err;
|
| 332 | }
|
| 333 | return desc_size;
|
| 334 | }
|
| 335 |
|
| 336 | static struct page *ext4_read_merkle_tree_page(struct inode *inode,
|
| 337 | pgoff_t index)
|
| 338 | {
|
| 339 | index += ext4_verity_metadata_pos(inode) >> PAGE_SHIFT;
|
| 340 | return generic_read_merkle_tree_page(inode, index);
|
| 341 | }
|
| 342 |
|
| 343 | static void ext4_readahead_merkle_tree(struct inode *inode, pgoff_t index,
|
| 344 | unsigned long nr_pages)
|
| 345 | {
|
| 346 | index += ext4_verity_metadata_pos(inode) >> PAGE_SHIFT;
|
| 347 | generic_readahead_merkle_tree(inode, index, nr_pages);
|
| 348 | }
|
| 349 |
|
| 350 | static int ext4_write_merkle_tree_block(struct file *file, const void *buf,
|
| 351 | u64 pos, unsigned int size,
|
| 352 | const u8 *zero_digest,
|
| 353 | unsigned int digest_size)
|
| 354 | {
|
| 355 | pos += ext4_verity_metadata_pos(file_inode(file));
|
| 356 |
|
| 357 | return pagecache_write(file_inode(file), buf, size, pos);
|
| 358 | }
|
| 359 |
|
| 360 | const struct fsverity_operations ext4_verityops = {
|
| 361 | .begin_enable_verity = ext4_begin_enable_verity,
|
| 362 | .end_enable_verity = ext4_end_enable_verity,
|
| 363 | .get_verity_descriptor = ext4_get_verity_descriptor,
|
| 364 | .read_merkle_tree_page = ext4_read_merkle_tree_page,
|
| 365 | .readahead_merkle_tree = ext4_readahead_merkle_tree,
|
| 366 | .write_merkle_tree_block = ext4_write_merkle_tree_block,
|
| 367 | };
|