Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ntfs: zero out stale data in straddle block beyond initialized_size

ntfs_read_iomap_begin_non_resident() rounds up MAPPED extents
to the block boundary of initialized_size. This ensures that
any subsequent blocks are treated as IOMAP_UNWRITTEN, but
it also causes the "straddle block" containing initialized_size
to be read from disk. The disk data beyond initialized_size in
this block is stale and must be zeroed to prevent data leakage.

Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>

authored by

Hyunchul Lee and committed by
Namjae Jeon
8b4064e6 8541d8f7

+45 -11
+45 -2
fs/ntfs/aops.c
··· 15 15 #include "debug.h" 16 16 #include "iomap.h" 17 17 18 + static void ntfs_iomap_read_end_io(struct bio *bio) 19 + { 20 + int error = blk_status_to_errno(bio->bi_status); 21 + struct folio_iter iter; 22 + 23 + bio_for_each_folio_all(iter, bio) { 24 + struct folio *folio = iter.folio; 25 + struct ntfs_inode *ni = NTFS_I(folio->mapping->host); 26 + s64 init_size; 27 + loff_t pos = folio_pos(folio); 28 + 29 + init_size = ni->initialized_size; 30 + if (pos + iter.offset < init_size && 31 + pos + iter.offset + iter.length > init_size) 32 + folio_zero_segment(folio, offset_in_folio(folio, init_size), 33 + iter.offset + iter.length); 34 + 35 + iomap_finish_folio_read(folio, iter.offset, iter.length, error); 36 + } 37 + bio_put(bio); 38 + } 39 + 40 + static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter, 41 + struct iomap_read_folio_ctx *ctx) 42 + { 43 + struct bio *bio = ctx->read_ctx; 44 + bio->bi_end_io = ntfs_iomap_read_end_io; 45 + submit_bio(bio); 46 + } 47 + 48 + static const struct iomap_read_ops ntfs_iomap_bio_read_ops = { 49 + .read_folio_range = iomap_bio_read_folio_range, 50 + .submit_read = ntfs_iomap_bio_submit_read, 51 + }; 52 + 18 53 /* 19 54 * ntfs_read_folio - Read data for a folio from the device 20 55 * @file: open file to which the folio @folio belongs or NULL ··· 70 35 static int ntfs_read_folio(struct file *file, struct folio *folio) 71 36 { 72 37 struct ntfs_inode *ni = NTFS_I(folio->mapping->host); 38 + struct iomap_read_folio_ctx ctx = { 39 + .cur_folio = folio, 40 + .ops = &ntfs_iomap_bio_read_ops, 41 + }; 73 42 74 43 /* 75 44 * Only $DATA attributes can be encrypted and only unnamed $DATA ··· 97 58 return ntfs_read_compressed_block(folio); 98 59 } 99 60 100 - iomap_bio_read_folio(folio, &ntfs_read_iomap_ops); 61 + iomap_read_folio(&ntfs_read_iomap_ops, &ctx, NULL); 101 62 return 0; 102 63 } 103 64 ··· 227 188 struct address_space *mapping = rac->mapping; 228 189 struct inode *inode = mapping->host; 229 190 struct ntfs_inode *ni = NTFS_I(inode); 191 + struct iomap_read_folio_ctx ctx = { 192 + .ops = &ntfs_iomap_bio_read_ops, 193 + .rac = rac, 194 + }; 230 195 231 196 /* 232 197 * Resident files are not cached in the page cache, ··· 238 195 */ 239 196 if (!NInoNonResident(ni) || NInoCompressed(ni)) 240 197 return; 241 - iomap_bio_readahead(rac, &ntfs_read_iomap_ops); 198 + iomap_readahead(&ntfs_read_iomap_ops, &ctx, NULL); 242 199 } 243 200 244 201 static int ntfs_writepages(struct address_space *mapping,
-9
fs/ntfs/file.c
··· 267 267 return err; 268 268 269 269 inode_dio_wait(vi); 270 - /* Serialize against page faults */ 271 - if (NInoNonResident(NTFS_I(vi)) && attr->ia_size < old_size) { 272 - err = iomap_truncate_page(vi, attr->ia_size, NULL, 273 - &ntfs_read_iomap_ops, 274 - &ntfs_iomap_folio_ops, NULL); 275 - if (err) 276 - return err; 277 - } 278 - 279 270 truncate_setsize(vi, attr->ia_size); 280 271 err = ntfs_truncate_vfs(vi, attr->ia_size, old_size); 281 272 if (err) {