Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d51ceaf authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: avoid wrong decrypted data from disk



1. Create a file in an encrypted directory
2. Do GC & drop caches
3. Read stale data before its bio for metapage was not issued yet

Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 2f476442
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -563,9 +563,6 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
		ctx->bio = bio;
		ctx->enabled_steps = post_read_steps;
		bio->bi_private = ctx;

		/* wait the page to be moved by cleaning */
		f2fs_wait_on_block_writeback(sbi, blkaddr);
	}

	return bio;
@@ -580,6 +577,9 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
	if (IS_ERR(bio))
		return PTR_ERR(bio);

	/* wait for GCed page writeback via META_MAPPING */
	f2fs_wait_on_block_writeback(inode, blkaddr);

	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
		bio_put(bio);
		return -EFAULT;
@@ -1556,6 +1556,12 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
			}
		}

		/*
		 * If the page is under writeback, we need to wait for
		 * its completion to see the correct decrypted data.
		 */
		f2fs_wait_on_block_writeback(inode, block_nr);

		if (bio_add_page(bio, page, blocksize, 0) < blocksize)
			goto submit_and_realloc;

@@ -1623,7 +1629,7 @@ static int encrypt_one_page(struct f2fs_io_info *fio)
		return 0;

	/* wait for GCed page writeback via META_MAPPING */
	f2fs_wait_on_block_writeback(fio->sbi, fio->old_blkaddr);
	f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);

retry_encrypt:
	fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
@@ -2380,10 +2386,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,

	f2fs_wait_on_page_writeback(page, DATA, false);

	/* wait for GCed page writeback via META_MAPPING */
	if (f2fs_post_read_required(inode))
		f2fs_wait_on_block_writeback(sbi, blkaddr);

	if (len == PAGE_SIZE || PageUptodate(page))
		return 0;

+1 −1
Original line number Diff line number Diff line
@@ -2971,7 +2971,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
			struct f2fs_io_info *fio, bool add_list);
void f2fs_wait_on_page_writeback(struct page *page,
			enum page_type type, bool ordered);
void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr);
void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
+1 −2
Original line number Diff line number Diff line
@@ -114,8 +114,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
	f2fs_wait_on_page_writeback(page, DATA, false);

	/* wait for GCed page writeback via META_MAPPING */
	if (f2fs_post_read_required(inode))
		f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr);
	f2fs_wait_on_block_writeback(inode, dn.data_blkaddr);

out_sem:
	up_read(&F2FS_I(inode)->i_mmap_sem);
+5 −1
Original line number Diff line number Diff line
@@ -3196,10 +3196,14 @@ void f2fs_wait_on_page_writeback(struct page *page,
	}
}

void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct page *cpage;

	if (!f2fs_post_read_required(inode))
		return;

	if (!is_valid_data_blkaddr(sbi, blkaddr))
		return;