0001
0002
0003 #include <linux/quotaops.h>
0004 #include <linux/uuid.h>
0005
0006 #include "ext4.h"
0007 #include "xattr.h"
0008 #include "ext4_jbd2.h"
0009
0010 static void ext4_fname_from_fscrypt_name(struct ext4_filename *dst,
0011 const struct fscrypt_name *src)
0012 {
0013 memset(dst, 0, sizeof(*dst));
0014
0015 dst->usr_fname = src->usr_fname;
0016 dst->disk_name = src->disk_name;
0017 dst->hinfo.hash = src->hash;
0018 dst->hinfo.minor_hash = src->minor_hash;
0019 dst->crypto_buf = src->crypto_buf;
0020 }
0021
0022 int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
0023 int lookup, struct ext4_filename *fname)
0024 {
0025 struct fscrypt_name name;
0026 int err;
0027
0028 err = fscrypt_setup_filename(dir, iname, lookup, &name);
0029 if (err)
0030 return err;
0031
0032 ext4_fname_from_fscrypt_name(fname, &name);
0033
0034 #if IS_ENABLED(CONFIG_UNICODE)
0035 err = ext4_fname_setup_ci_filename(dir, iname, fname);
0036 #endif
0037 return err;
0038 }
0039
0040 int ext4_fname_prepare_lookup(struct inode *dir, struct dentry *dentry,
0041 struct ext4_filename *fname)
0042 {
0043 struct fscrypt_name name;
0044 int err;
0045
0046 err = fscrypt_prepare_lookup(dir, dentry, &name);
0047 if (err)
0048 return err;
0049
0050 ext4_fname_from_fscrypt_name(fname, &name);
0051
0052 #if IS_ENABLED(CONFIG_UNICODE)
0053 err = ext4_fname_setup_ci_filename(dir, &dentry->d_name, fname);
0054 #endif
0055 return err;
0056 }
0057
0058 void ext4_fname_free_filename(struct ext4_filename *fname)
0059 {
0060 struct fscrypt_name name;
0061
0062 name.crypto_buf = fname->crypto_buf;
0063 fscrypt_free_filename(&name);
0064
0065 fname->crypto_buf.name = NULL;
0066 fname->usr_fname = NULL;
0067 fname->disk_name.name = NULL;
0068
0069 #if IS_ENABLED(CONFIG_UNICODE)
0070 kfree(fname->cf_name.name);
0071 fname->cf_name.name = NULL;
0072 #endif
0073 }
0074
0075 static bool uuid_is_zero(__u8 u[16])
0076 {
0077 int i;
0078
0079 for (i = 0; i < 16; i++)
0080 if (u[i])
0081 return false;
0082 return true;
0083 }
0084
0085 int ext4_ioctl_get_encryption_pwsalt(struct file *filp, void __user *arg)
0086 {
0087 struct super_block *sb = file_inode(filp)->i_sb;
0088 struct ext4_sb_info *sbi = EXT4_SB(sb);
0089 int err, err2;
0090 handle_t *handle;
0091
0092 if (!ext4_has_feature_encrypt(sb))
0093 return -EOPNOTSUPP;
0094
0095 if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) {
0096 err = mnt_want_write_file(filp);
0097 if (err)
0098 return err;
0099 handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
0100 if (IS_ERR(handle)) {
0101 err = PTR_ERR(handle);
0102 goto pwsalt_err_exit;
0103 }
0104 err = ext4_journal_get_write_access(handle, sb, sbi->s_sbh,
0105 EXT4_JTR_NONE);
0106 if (err)
0107 goto pwsalt_err_journal;
0108 lock_buffer(sbi->s_sbh);
0109 generate_random_uuid(sbi->s_es->s_encrypt_pw_salt);
0110 ext4_superblock_csum_set(sb);
0111 unlock_buffer(sbi->s_sbh);
0112 err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh);
0113 pwsalt_err_journal:
0114 err2 = ext4_journal_stop(handle);
0115 if (err2 && !err)
0116 err = err2;
0117 pwsalt_err_exit:
0118 mnt_drop_write_file(filp);
0119 if (err)
0120 return err;
0121 }
0122
0123 if (copy_to_user(arg, sbi->s_es->s_encrypt_pw_salt, 16))
0124 return -EFAULT;
0125 return 0;
0126 }
0127
0128 static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
0129 {
0130 return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
0131 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len);
0132 }
0133
0134 static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
0135 void *fs_data)
0136 {
0137 handle_t *handle = fs_data;
0138 int res, res2, credits, retries = 0;
0139
0140
0141
0142
0143
0144
0145
0146 if (inode->i_ino == EXT4_ROOT_INO)
0147 return -EPERM;
0148
0149 if (WARN_ON_ONCE(IS_DAX(inode) && i_size_read(inode)))
0150 return -EINVAL;
0151
0152 if (ext4_test_inode_flag(inode, EXT4_INODE_DAX))
0153 return -EOPNOTSUPP;
0154
0155 res = ext4_convert_inline_data(inode);
0156 if (res)
0157 return res;
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 if (handle) {
0168 res = ext4_xattr_set_handle(handle, inode,
0169 EXT4_XATTR_INDEX_ENCRYPTION,
0170 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
0171 ctx, len, 0);
0172 if (!res) {
0173 ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
0174 ext4_clear_inode_state(inode,
0175 EXT4_STATE_MAY_INLINE_DATA);
0176
0177
0178
0179
0180 ext4_set_inode_flags(inode, false);
0181 }
0182 return res;
0183 }
0184
0185 res = dquot_initialize(inode);
0186 if (res)
0187 return res;
0188 retry:
0189 res = ext4_xattr_set_credits(inode, len, false ,
0190 &credits);
0191 if (res)
0192 return res;
0193
0194 handle = ext4_journal_start(inode, EXT4_HT_MISC, credits);
0195 if (IS_ERR(handle))
0196 return PTR_ERR(handle);
0197
0198 res = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_ENCRYPTION,
0199 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
0200 ctx, len, 0);
0201 if (!res) {
0202 ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
0203
0204
0205
0206
0207 ext4_set_inode_flags(inode, false);
0208 res = ext4_mark_inode_dirty(handle, inode);
0209 if (res)
0210 EXT4_ERROR_INODE(inode, "Failed to mark inode dirty");
0211 }
0212 res2 = ext4_journal_stop(handle);
0213
0214 if (res == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
0215 goto retry;
0216 if (!res)
0217 res = res2;
0218 return res;
0219 }
0220
0221 static const union fscrypt_policy *ext4_get_dummy_policy(struct super_block *sb)
0222 {
0223 return EXT4_SB(sb)->s_dummy_enc_policy.policy;
0224 }
0225
0226 static bool ext4_has_stable_inodes(struct super_block *sb)
0227 {
0228 return ext4_has_feature_stable_inodes(sb);
0229 }
0230
0231 static void ext4_get_ino_and_lblk_bits(struct super_block *sb,
0232 int *ino_bits_ret, int *lblk_bits_ret)
0233 {
0234 *ino_bits_ret = 8 * sizeof(EXT4_SB(sb)->s_es->s_inodes_count);
0235 *lblk_bits_ret = 8 * sizeof(ext4_lblk_t);
0236 }
0237
0238 const struct fscrypt_operations ext4_cryptops = {
0239 .key_prefix = "ext4:",
0240 .get_context = ext4_get_context,
0241 .set_context = ext4_set_context,
0242 .get_dummy_policy = ext4_get_dummy_policy,
0243 .empty_dir = ext4_empty_dir,
0244 .has_stable_inodes = ext4_has_stable_inodes,
0245 .get_ino_and_lblk_bits = ext4_get_ino_and_lblk_bits,
0246 };