Commit 200204f5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents b229b6ca ccd30a47
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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) {
+2 −2
Original line number Diff line number Diff line
@@ -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)
{
}