diff options
| -rw-r--r-- | fs/ext4/crypto.c | 54 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 8 | ||||
| -rw-r--r-- | fs/ext4/ioctl.c | 59 | 
3 files changed, 64 insertions, 57 deletions
| diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index f8333927f0f6..e20ac0654b3f 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c @@ -1,6 +1,7 @@  // SPDX-License-Identifier: GPL-2.0  #include <linux/quotaops.h> +#include <linux/uuid.h>  #include "ext4.h"  #include "xattr.h" @@ -71,6 +72,59 @@ void ext4_fname_free_filename(struct ext4_filename *fname)  #endif  } +static bool uuid_is_zero(__u8 u[16]) +{ +	int i; + +	for (i = 0; i < 16; i++) +		if (u[i]) +			return false; +	return true; +} + +int ext4_ioctl_get_encryption_pwsalt(struct file *filp, void __user *arg) +{ +	struct super_block *sb = file_inode(filp)->i_sb; +	struct ext4_sb_info *sbi = EXT4_SB(sb); +	int err, err2; +	handle_t *handle; + +	if (!ext4_has_feature_encrypt(sb)) +		return -EOPNOTSUPP; + +	if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) { +		err = mnt_want_write_file(filp); +		if (err) +			return err; +		handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); +		if (IS_ERR(handle)) { +			err = PTR_ERR(handle); +			goto pwsalt_err_exit; +		} +		err = ext4_journal_get_write_access(handle, sb, sbi->s_sbh, +						    EXT4_JTR_NONE); +		if (err) +			goto pwsalt_err_journal; +		lock_buffer(sbi->s_sbh); +		generate_random_uuid(sbi->s_es->s_encrypt_pw_salt); +		ext4_superblock_csum_set(sb); +		unlock_buffer(sbi->s_sbh); +		err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); +pwsalt_err_journal: +		err2 = ext4_journal_stop(handle); +		if (err2 && !err) +			err = err2; +pwsalt_err_exit: +		mnt_drop_write_file(filp); +		if (err) +			return err; +	} + +	if (copy_to_user(arg, sbi->s_es->s_encrypt_pw_salt, 16)) +		return -EFAULT; +	return 0; +} +  static int ext4_get_context(struct inode *inode, void *ctx, size_t len)  {  	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION, diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d815d07a8c3d..a16d77b29277 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2745,6 +2745,8 @@ int ext4_fname_prepare_lookup(struct inode *dir, struct dentry *dentry,  void ext4_fname_free_filename(struct ext4_filename *fname); +int ext4_ioctl_get_encryption_pwsalt(struct file *filp, void __user *arg); +  #else /* !CONFIG_FS_ENCRYPTION */  static inline int ext4_fname_setup_filename(struct inode *dir,  					    const struct qstr *iname, @@ -2777,6 +2779,12 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname)  	fname->cf_name.name = NULL;  #endif  } + +static inline int ext4_ioctl_get_encryption_pwsalt(struct file *filp, +						   void __user *arg) +{ +	return -EOPNOTSUPP; +}  #endif /* !CONFIG_FS_ENCRYPTION */  /* dir.c */ diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index ba44fa1be70a..d8639aaed3f6 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -16,7 +16,6 @@  #include <linux/file.h>  #include <linux/quotaops.h>  #include <linux/random.h> -#include <linux/uuid.h>  #include <linux/uaccess.h>  #include <linux/delay.h>  #include <linux/iversion.h> @@ -504,18 +503,6 @@ journal_err_out:  	return err;  } -#ifdef CONFIG_FS_ENCRYPTION -static int uuid_is_zero(__u8 u[16]) -{ -	int	i; - -	for (i = 0; i < 16; i++) -		if (u[i]) -			return 0; -	return 1; -} -#endif -  /*   * If immutable is set and we are not clearing it, we're not allowed to change   * anything else in the inode.  Don't error out if we're only trying to set @@ -1432,51 +1419,9 @@ resizefs_out:  			return -EOPNOTSUPP;  		return fscrypt_ioctl_set_policy(filp, (const void __user *)arg); -	case FS_IOC_GET_ENCRYPTION_PWSALT: { -#ifdef CONFIG_FS_ENCRYPTION -		int err, err2; -		struct ext4_sb_info *sbi = EXT4_SB(sb); -		handle_t *handle; +	case FS_IOC_GET_ENCRYPTION_PWSALT: +		return ext4_ioctl_get_encryption_pwsalt(filp, (void __user *)arg); -		if (!ext4_has_feature_encrypt(sb)) -			return -EOPNOTSUPP; -		if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) { -			err = mnt_want_write_file(filp); -			if (err) -				return err; -			handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); -			if (IS_ERR(handle)) { -				err = PTR_ERR(handle); -				goto pwsalt_err_exit; -			} -			err = ext4_journal_get_write_access(handle, sb, -							    sbi->s_sbh, -							    EXT4_JTR_NONE); -			if (err) -				goto pwsalt_err_journal; -			lock_buffer(sbi->s_sbh); -			generate_random_uuid(sbi->s_es->s_encrypt_pw_salt); -			ext4_superblock_csum_set(sb); -			unlock_buffer(sbi->s_sbh); -			err = ext4_handle_dirty_metadata(handle, NULL, -							 sbi->s_sbh); -		pwsalt_err_journal: -			err2 = ext4_journal_stop(handle); -			if (err2 && !err) -				err = err2; -		pwsalt_err_exit: -			mnt_drop_write_file(filp); -			if (err) -				return err; -		} -		if (copy_to_user((void __user *) arg, -				 sbi->s_es->s_encrypt_pw_salt, 16)) -			return -EFAULT; -		return 0; -#else -		return -EOPNOTSUPP; -#endif -	}  	case FS_IOC_GET_ENCRYPTION_POLICY:  		if (!ext4_has_feature_encrypt(sb))  			return -EOPNOTSUPP; | 
