fscrypt fix for 6.1-rc3

Fix a memory leak that was introduced by a change that went into -rc1.
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCY1oM6BQcZWJpZ2dlcnNA
 Z29vZ2xlLmNvbQAKCRDzXCl4vpKOK3ixAP9IY1TdJu64uKTofFdYvO/wBASpdszm
 GkY1QnEFxATA9AEAwRswZgaGiuKj4hFBeIWmu9+luT4T7kVIcaumslTyTg8=
 =YinC
 -----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 memory leak that was introduced by a change that went into -rc1"

* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
  fscrypt: fix keyring memory leak on mount failure
This commit is contained in:
Linus Torvalds 2022-10-27 11:44:18 -07:00
commit 200204f56f
3 changed files with 15 additions and 9 deletions

View File

@ -205,14 +205,19 @@ static int allocate_filesystem_keyring(struct super_block *sb)
}
/*
* This is called at unmount time to release all encryption keys that have been
* added to the filesystem, along with the keyring that contains them.
* Release all encryption keys that have been added to the filesystem, along
* with the keyring that contains them.
*
* Note that besides clearing and freeing memory, this might need to evict keys
* from the keyslots of an inline crypto engine. Therefore, this must be called
* while the filesystem's underlying block device(s) are still available.
* This is called at unmount time. The filesystem's underlying block device(s)
* are still available at this time; this is important because after user file
* accesses have been allowed, this function may need to evict keys from the
* keyslots of an inline crypto engine, which requires the block device(s).
*
* This is also called when the super_block is being freed. This is needed to
* avoid a memory leak if mounting fails after the "test_dummy_encryption"
* option was processed, as in that case the unmount-time call isn't made.
*/
void fscrypt_sb_delete(struct super_block *sb)
void fscrypt_destroy_keyring(struct super_block *sb)
{
struct fscrypt_keyring *keyring = sb->s_master_keys;
size_t i;

View File

@ -291,6 +291,7 @@ static void __put_super(struct super_block *s)
WARN_ON(s->s_inode_lru.node);
WARN_ON(!list_empty(&s->s_mounts));
security_sb_free(s);
fscrypt_destroy_keyring(s);
put_user_ns(s->s_user_ns);
kfree(s->s_subtype);
call_rcu(&s->rcu, destroy_super_rcu);
@ -479,7 +480,7 @@ void generic_shutdown_super(struct super_block *sb)
evict_inodes(sb);
/* only nonzero refcount inodes can have marks */
fsnotify_sb_delete(sb);
fscrypt_sb_delete(sb);
fscrypt_destroy_keyring(sb);
security_sb_delete(sb);
if (sb->s_dio_done_wq) {

View File

@ -307,7 +307,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
}
/* keyring.c */
void fscrypt_sb_delete(struct super_block *sb);
void fscrypt_destroy_keyring(struct super_block *sb);
int fscrypt_ioctl_add_key(struct file *filp, void __user *arg);
int fscrypt_add_test_dummy_key(struct super_block *sb,
const struct fscrypt_dummy_policy *dummy_policy);
@ -521,7 +521,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
}
/* keyring.c */
static inline void fscrypt_sb_delete(struct super_block *sb)
static inline void fscrypt_destroy_keyring(struct super_block *sb)
{
}