mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-21 13:57:57 +07:00
ext4 crypto: enable filename encryption
Signed-off-by: Uday Savagaonkar <savagaon@google.com> Signed-off-by: Ildar Muslukhov <ildarm@google.com> Signed-off-by: Michael Halcrow <mhalcrow@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
1f3862b557
commit
4461471107
@ -108,7 +108,10 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
|||||||
int err;
|
int err;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
|
struct buffer_head *bh = NULL;
|
||||||
int dir_has_error = 0;
|
int dir_has_error = 0;
|
||||||
|
struct ext4_fname_crypto_ctx *enc_ctx = NULL;
|
||||||
|
struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
|
||||||
|
|
||||||
if (is_dx_dir(inode)) {
|
if (is_dx_dir(inode)) {
|
||||||
err = ext4_dx_readdir(file, ctx);
|
err = ext4_dx_readdir(file, ctx);
|
||||||
@ -125,17 +128,28 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
|||||||
|
|
||||||
if (ext4_has_inline_data(inode)) {
|
if (ext4_has_inline_data(inode)) {
|
||||||
int has_inline_data = 1;
|
int has_inline_data = 1;
|
||||||
int ret = ext4_read_inline_dir(file, ctx,
|
err = ext4_read_inline_dir(file, ctx,
|
||||||
&has_inline_data);
|
&has_inline_data);
|
||||||
if (has_inline_data)
|
if (has_inline_data)
|
||||||
return ret;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
enc_ctx = ext4_get_fname_crypto_ctx(inode, EXT4_NAME_LEN);
|
||||||
|
if (IS_ERR(enc_ctx))
|
||||||
|
return PTR_ERR(enc_ctx);
|
||||||
|
if (enc_ctx) {
|
||||||
|
err = ext4_fname_crypto_alloc_buffer(enc_ctx, EXT4_NAME_LEN,
|
||||||
|
&fname_crypto_str);
|
||||||
|
if (err < 0) {
|
||||||
|
ext4_put_fname_crypto_ctx(&enc_ctx);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = ctx->pos & (sb->s_blocksize - 1);
|
offset = ctx->pos & (sb->s_blocksize - 1);
|
||||||
|
|
||||||
while (ctx->pos < inode->i_size) {
|
while (ctx->pos < inode->i_size) {
|
||||||
struct ext4_map_blocks map;
|
struct ext4_map_blocks map;
|
||||||
struct buffer_head *bh = NULL;
|
|
||||||
|
|
||||||
map.m_lblk = ctx->pos >> EXT4_BLOCK_SIZE_BITS(sb);
|
map.m_lblk = ctx->pos >> EXT4_BLOCK_SIZE_BITS(sb);
|
||||||
map.m_len = 1;
|
map.m_len = 1;
|
||||||
@ -178,6 +192,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
|||||||
(unsigned long long)ctx->pos);
|
(unsigned long long)ctx->pos);
|
||||||
ctx->pos += sb->s_blocksize - offset;
|
ctx->pos += sb->s_blocksize - offset;
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
|
bh = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set_buffer_verified(bh);
|
set_buffer_verified(bh);
|
||||||
@ -224,25 +239,44 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
|||||||
offset += ext4_rec_len_from_disk(de->rec_len,
|
offset += ext4_rec_len_from_disk(de->rec_len,
|
||||||
sb->s_blocksize);
|
sb->s_blocksize);
|
||||||
if (le32_to_cpu(de->inode)) {
|
if (le32_to_cpu(de->inode)) {
|
||||||
|
if (enc_ctx == NULL) {
|
||||||
|
/* Directory is not encrypted */
|
||||||
if (!dir_emit(ctx, de->name,
|
if (!dir_emit(ctx, de->name,
|
||||||
de->name_len,
|
de->name_len,
|
||||||
le32_to_cpu(de->inode),
|
le32_to_cpu(de->inode),
|
||||||
get_dtype(sb, de->file_type))) {
|
get_dtype(sb, de->file_type)))
|
||||||
brelse(bh);
|
goto done;
|
||||||
return 0;
|
} else {
|
||||||
|
/* Directory is encrypted */
|
||||||
|
err = ext4_fname_disk_to_usr(enc_ctx,
|
||||||
|
de, &fname_crypto_str);
|
||||||
|
if (err < 0)
|
||||||
|
goto errout;
|
||||||
|
if (!dir_emit(ctx,
|
||||||
|
fname_crypto_str.name, err,
|
||||||
|
le32_to_cpu(de->inode),
|
||||||
|
get_dtype(sb, de->file_type)))
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx->pos += ext4_rec_len_from_disk(de->rec_len,
|
ctx->pos += ext4_rec_len_from_disk(de->rec_len,
|
||||||
sb->s_blocksize);
|
sb->s_blocksize);
|
||||||
}
|
}
|
||||||
offset = 0;
|
if ((ctx->pos < inode->i_size) && !dir_relax(inode))
|
||||||
|
goto done;
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
if (ctx->pos < inode->i_size) {
|
bh = NULL;
|
||||||
if (!dir_relax(inode))
|
offset = 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
done:
|
||||||
return 0;
|
err = 0;
|
||||||
|
errout:
|
||||||
|
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||||
|
ext4_put_fname_crypto_ctx(&enc_ctx);
|
||||||
|
ext4_fname_crypto_free_buffer(&fname_crypto_str);
|
||||||
|
#endif
|
||||||
|
brelse(bh);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int is_32bit_api(void)
|
static inline int is_32bit_api(void)
|
||||||
|
@ -1033,11 +1033,28 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
|
|||||||
ext4_set_inode_state(inode, EXT4_STATE_NEW);
|
ext4_set_inode_state(inode, EXT4_STATE_NEW);
|
||||||
|
|
||||||
ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
|
ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
|
||||||
|
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||||
|
if ((sbi->s_file_encryption_mode == EXT4_ENCRYPTION_MODE_INVALID) &&
|
||||||
|
(sbi->s_dir_encryption_mode == EXT4_ENCRYPTION_MODE_INVALID)) {
|
||||||
|
ei->i_inline_off = 0;
|
||||||
|
if (EXT4_HAS_INCOMPAT_FEATURE(sb,
|
||||||
|
EXT4_FEATURE_INCOMPAT_INLINE_DATA))
|
||||||
|
ext4_set_inode_state(inode,
|
||||||
|
EXT4_STATE_MAY_INLINE_DATA);
|
||||||
|
} else {
|
||||||
|
/* Inline data and encryption are incompatible
|
||||||
|
* We turn off inline data since encryption is enabled */
|
||||||
|
ei->i_inline_off = 1;
|
||||||
|
if (EXT4_HAS_INCOMPAT_FEATURE(sb,
|
||||||
|
EXT4_FEATURE_INCOMPAT_INLINE_DATA))
|
||||||
|
ext4_clear_inode_state(inode,
|
||||||
|
EXT4_STATE_MAY_INLINE_DATA);
|
||||||
|
}
|
||||||
|
#else
|
||||||
ei->i_inline_off = 0;
|
ei->i_inline_off = 0;
|
||||||
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_INLINE_DATA))
|
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_INLINE_DATA))
|
||||||
ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
|
ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
|
||||||
|
#endif
|
||||||
ret = inode;
|
ret = inode;
|
||||||
err = dquot_alloc_inode(inode);
|
err = dquot_alloc_inode(inode);
|
||||||
if (err)
|
if (err)
|
||||||
|
Loading…
Reference in New Issue
Block a user