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

Commit af4ef71b authored by Jaegeuk Kim's avatar Jaegeuk Kim Committed by Gerrit - the friendly Code Review server
Browse files

dm-default-key, f2fs, ICE: support dm-default-key with f2fs/ICE



This patch fixes assigning bi_crypt_key for moving data which was previously
encrypted by f2fs.

Note that, dm-default-key should not assign bi_crypt_key, if bi_crypt_skip is
set.

The bug sceanrios is:

1. write data with user key by f2fs
  -  ENC(KU, IVU, DATA)
2. log out user key
3. read data #1 w/o user key from LBA #a
4. dm-default-key assigns default key
  - DEC(KD, LBA#a, ENC(KU, IVU, DATA))
5. write data #1 w/o user key into LBA #b
6. dm-default-key assigns default key
  - ENC(KD, LBA#b, DEC(KD, LBA#a, ENC(KU, IVU, DATA)))
7. Read DATA out with valid logged-in user key
  - DEC(KU, IVU, ENC(KD, LBA#b, DEC(KD, LBA#a, ENC(KU, IVU, DATA))))

So, this patch introduces bi_crypt_skip to avoid 4. ~ 6 with right flow:
1. write data with user key by f2fs
  -  ENC(KU, IVU, DATA)
2. log out user key
3. read data #1 w/o user key from LBA #a
4. dm-default-key skip to assign default key
  - ENC(KU, IVU, DATA)
5. write data #1 w/o user key into LBA #b
6. dm-default-key skips to assign default key
  - ENC(KU, IVU, DATA)
7. Try to read DATA with valid logged-in user key
  - DEC(KU, IVU, ENC(KU, IVU, DATA))

Bug: 68721442
Change-Id: Icefe85f608b7c3c84beb2bfa4267efd0f3787453
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@google.com>
Signed-off-by: default avatarShivaprasad Hongal <shongal@codeaurora.org>
parent 1611298c
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -580,8 +580,12 @@ EXPORT_SYMBOL(bio_phys_segments);
static inline void bio_clone_crypt_key(struct bio *dst, const struct bio *src)
{
#ifdef CONFIG_PFK
	dst->bi_crypt_key = src->bi_crypt_key;
	dst->bi_iter.bi_dun = src->bi_iter.bi_dun;
#ifdef CONFIG_DM_DEFAULT_KEY
	dst->bi_crypt_key = src->bi_crypt_key;
	dst->bi_crypt_skip = src->bi_crypt_skip;
#endif
	dst->bi_dio_inode = src->bi_dio_inode;
#endif
}

+14 −1
Original line number Diff line number Diff line
@@ -126,16 +126,29 @@ void fscrypt_set_ice_dun(const struct inode *inode, struct bio *bio, u64 dun)
}
EXPORT_SYMBOL(fscrypt_set_ice_dun);

void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip)
{
#ifdef CONFIG_DM_DEFAULT_KEY
	bio->bi_crypt_skip = bi_crypt_skip;
#endif
}
EXPORT_SYMBOL(fscrypt_set_ice_skip);

/*
 * This function will be used for filesystem when deciding to merge bios.
 * Basic assumption is, if inline_encryption is set, single bio has to
 * guarantee consecutive LBAs as well as ino|pg->index.
 */
bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted)
bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted,
						int bi_crypt_skip)
{
	if (!bio)
		return true;

#ifdef CONFIG_DM_DEFAULT_KEY
	if (bi_crypt_skip != bio->bi_crypt_skip)
		return false;
#endif
	/* if both of them are not encrypted, no further check is needed */
	if (!bio_dun(bio) && !bio_encrypted)
		return true;
+6 −3
Original line number Diff line number Diff line
@@ -451,6 +451,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)

	if (f2fs_may_encrypt_bio(inode, fio))
		fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, fio->page));
	fscrypt_set_ice_skip(bio, fio->encrypted_page ? 1 : 0);

	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
		bio_put(bio);
@@ -473,6 +474,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
	struct page *bio_page;
	struct inode *inode;
	bool bio_encrypted;
	int bi_crypt_skip;
	u64 dun;
	int err = 0;

@@ -499,6 +501,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
	bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;
	inode = fio->page->mapping->host;
	dun = PG_DUN(inode, fio->page);
	bi_crypt_skip = fio->encrypted_page ? 1 : 0;
	bio_encrypted = f2fs_may_encrypt_bio(inode, fio);

	/* set submitted = true as a return value */
@@ -512,7 +515,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
		__submit_merged_bio(io);

	/* ICE support */
	if (!fscrypt_mergeable_bio(io->bio, dun, bio_encrypted))
	if (!fscrypt_mergeable_bio(io->bio, dun, bio_encrypted, bi_crypt_skip))
		__submit_merged_bio(io);

alloc_new:
@@ -528,7 +531,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
						fio->type, fio->temp);
		if (bio_encrypted)
			fscrypt_set_ice_dun(inode, io->bio, dun);

		fscrypt_set_ice_skip(io->bio, bi_crypt_skip);
		io->fio = *fio;
	}

@@ -1539,7 +1542,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,

		dun = PG_DUN(inode, page);
		bio_encrypted = f2fs_may_encrypt_bio(inode, NULL);
		if (!fscrypt_mergeable_bio(bio, dun, bio_encrypted)) {
		if (!fscrypt_mergeable_bio(bio, dun, bio_encrypted, 0)) {
			__submit_bio(F2FS_I_SB(inode), bio, DATA);
			bio = NULL;
		}
+3 −0
Original line number Diff line number Diff line
@@ -104,6 +104,9 @@ struct bio {
	/* Encryption key to use (NULL if none) */
	const struct blk_encryption_key	*bi_crypt_key;
#endif
#ifdef CONFIG_DM_DEFAULT_KEY
	int bi_crypt_skip;
#endif

	unsigned short		bi_vcnt;	/* how many bio_vec's */

+6 −1
Original line number Diff line number Diff line
@@ -193,8 +193,13 @@ static inline int fscrypt_using_hardware_encryption(const struct inode *inode)
static inline void fscrypt_set_ice_dun(const struct inode *inode,
		struct bio *bio, u64 dun){}

static inline void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip)
{
	return;
}

static inline bool fscrypt_mergeable_bio(struct bio *bio,
		sector_t iv_block, bool bio_encrypted)
		sector_t iv_block, bool bio_encrypted, int bi_crypt_skip)
{
	return true;
}
Loading