fscrypt fix for v5.6-rc6
Fix a bug where if userspace is writing to encrypted files while the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (introduced in v5.4) is running, dirty inodes could be evicted, causing writes could be lost or the filesystem to hang due to a use-after-free. This was encountered during real-world use, not just theoretical. Tested with the existing fscrypt xfstests, and with a new xfstest I wrote to reproduce this bug. This fix does expose an existing bug with '-o lazytime' that Ted is working on fixing, but this fix is more critical and needed anyway regardless of the lazytime fix. -----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCXmk8HxQcZWJpZ2dlcnNA Z29vZ2xlLmNvbQAKCRDzXCl4vpKOK4YiAQC1RZyH4/mZ890Or6s8SzCgJTVmiLk9 ZTO/56XmLte6LAD+IBAExqDkkybmAF0rQ4kY1oL75f/e/nEs+50TXra9NQc= =s2KD -----END PGP SIGNATURE----- Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt Pull fscrypt fix from Eric Biggers: "Fix a bug where if userspace is writing to encrypted files while the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (introduced in v5.4) is running, dirty inodes could be evicted, causing writes could be lost or the filesystem to hang due to a use-after-free. This was encountered during real-world use, not just theoretical. Tested with the existing fscrypt xfstests, and with a new xfstest I wrote to reproduce this bug. This fix does expose an existing bug with '-o lazytime' that Ted is working on fixing, but this fix is more critical and needed anyway regardless of the lazytime fix" * tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt: fscrypt: don't evict dirty inodes after removing key
This commit is contained in:
commit
e6e6ec48dd
|
@ -538,6 +538,15 @@ int fscrypt_drop_inode(struct inode *inode)
|
|||
return 0;
|
||||
mk = ci->ci_master_key->payload.data[0];
|
||||
|
||||
/*
|
||||
* With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes
|
||||
* protected by the key were cleaned by sync_filesystem(). But if
|
||||
* userspace is still using the files, inodes can be dirtied between
|
||||
* then and now. We mustn't lose any writes, so skip dirty inodes here.
|
||||
*/
|
||||
if (inode->i_state & I_DIRTY_ALL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Note: since we aren't holding ->mk_secret_sem, the result here can
|
||||
* immediately become outdated. But there's no correctness problem with
|
||||
|
|
Loading…
Reference in New Issue