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

Commit 2b6ff022 authored by Eric Biggers's avatar Eric Biggers Committed by Alistair Delva
Browse files

ANDROID: sdcardfs: evict dentries on fscrypt key removal



Use the fscrypt key removal notifier chain to make sdcardfs evict its
dentries when an fscrypt key is about to be removed.  This is needed for
the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to properly "lock" the encrypted
files underneath sdcardfs when an Android user is stopped.

Test: pm create-user 10
      am start-user 10
      find /data/media/10/    # filenames are in plaintext form
      am stop-user 10
      find /data/media/10/    # filenames are in ciphertext form

      (But currently the kernel and vold still warn about other files
      still being open, due to b/140762419)

Bug: 120446149
Bug: 142275883
Change-Id: I83b451a2bc40c72fcd01d24aa5c34ad8de427534
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
parent 98261f39
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include "sdcardfs.h"
#include "sdcardfs.h"
#include <linux/fs_context.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/fs_parser.h>
#include <linux/fscrypt.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/parser.h>
#include <linux/parser.h>
@@ -293,6 +294,9 @@ static int __sdcardfs_fill_super(
	list_add(&sb_info->list, &sdcardfs_super_list);
	list_add(&sb_info->list, &sdcardfs_super_list);
	mutex_unlock(&sdcardfs_super_list_lock);
	mutex_unlock(&sdcardfs_super_list_lock);


	sb_info->fscrypt_nb.notifier_call = sdcardfs_on_fscrypt_key_removed;
	fscrypt_register_key_removal_notifier(&sb_info->fscrypt_nb);

	if (!(fc->sb_flags & SB_SILENT))
	if (!(fc->sb_flags & SB_SILENT))
		pr_info("sdcardfs: mounted on top of %s type %s\n",
		pr_info("sdcardfs: mounted on top of %s type %s\n",
				dev_name, lower_sb->s_type->name);
				dev_name, lower_sb->s_type->name);
@@ -331,6 +335,9 @@ void sdcardfs_kill_sb(struct super_block *sb)


	if (sb->s_magic == SDCARDFS_SUPER_MAGIC && sb->s_fs_info) {
	if (sb->s_magic == SDCARDFS_SUPER_MAGIC && sb->s_fs_info) {
		sbi = SDCARDFS_SB(sb);
		sbi = SDCARDFS_SB(sb);

		fscrypt_unregister_key_removal_notifier(&sbi->fscrypt_nb);

		mutex_lock(&sdcardfs_super_list_lock);
		mutex_lock(&sdcardfs_super_list_lock);
		list_del(&sbi->list);
		list_del(&sbi->list);
		mutex_unlock(&sdcardfs_super_list_lock);
		mutex_unlock(&sdcardfs_super_list_lock);
+3 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,8 @@ extern struct inode *sdcardfs_iget(struct super_block *sb,
				 struct inode *lower_inode, userid_t id);
				 struct inode *lower_inode, userid_t id);
extern int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
extern int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
			    struct path *lower_path, userid_t id);
			    struct path *lower_path, userid_t id);
extern int sdcardfs_on_fscrypt_key_removed(struct notifier_block *nb,
					   unsigned long action, void *data);


/* file private data */
/* file private data */
struct sdcardfs_file_info {
struct sdcardfs_file_info {
@@ -231,6 +233,7 @@ struct sdcardfs_sb_info {
	struct path obbpath;
	struct path obbpath;
	void *pkgl_id;
	void *pkgl_id;
	struct list_head list;
	struct list_head list;
	struct notifier_block fscrypt_nb;
};
};


/*
/*
+17 −0
Original line number Original line Diff line number Diff line
@@ -282,6 +282,23 @@ static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
	return 0;
	return 0;
};
};


int sdcardfs_on_fscrypt_key_removed(struct notifier_block *nb,
				    unsigned long action, void *data)
{
	struct sdcardfs_sb_info *sbi = container_of(nb, struct sdcardfs_sb_info,
						    fscrypt_nb);

	/*
	 * Evict any unused sdcardfs dentries (and hence any unused sdcardfs
	 * inodes, since sdcardfs doesn't cache unpinned inodes by themselves)
	 * so that the lower filesystem's encrypted inodes can be evicted.
	 * This is needed to make the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl
	 * properly "lock" the files underneath the sdcardfs mount.
	 */
	shrink_dcache_sb(sbi->sb);
	return NOTIFY_OK;
}

const struct super_operations sdcardfs_sops = {
const struct super_operations sdcardfs_sops = {
	.put_super	= sdcardfs_put_super,
	.put_super	= sdcardfs_put_super,
	.statfs		= sdcardfs_statfs,
	.statfs		= sdcardfs_statfs,