Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
56735be0
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
56735be0
编写于
1月 08, 2017
作者:
T
Theodore Ts'o
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'fscrypt' into d
上级
a121103c
a5d431ef
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
263 addition
and
301 deletion
+263
-301
fs/crypto/Kconfig
fs/crypto/Kconfig
+0
-1
fs/crypto/Makefile
fs/crypto/Makefile
+1
-0
fs/crypto/bio.c
fs/crypto/bio.c
+145
-0
fs/crypto/crypto.c
fs/crypto/crypto.c
+16
-141
fs/crypto/fname.c
fs/crypto/fname.c
+2
-2
fs/crypto/fscrypt_private.h
fs/crypto/fscrypt_private.h
+15
-1
fs/crypto/keyinfo.c
fs/crypto/keyinfo.c
+17
-29
fs/crypto/policy.c
fs/crypto/policy.c
+34
-61
fs/ext4/ext4.h
fs/ext4/ext4.h
+0
-11
fs/ext4/ialloc.c
fs/ext4/ialloc.c
+1
-1
fs/ext4/namei.c
fs/ext4/namei.c
+15
-1
fs/ext4/super.c
fs/ext4/super.c
+1
-12
fs/f2fs/dir.c
fs/f2fs/dir.c
+4
-1
fs/f2fs/f2fs.h
fs/f2fs/f2fs.h
+0
-9
fs/f2fs/namei.c
fs/f2fs/namei.c
+2
-2
fs/f2fs/super.c
fs/f2fs/super.c
+1
-13
fs/ubifs/crypto.c
fs/ubifs/crypto.c
+1
-10
include/linux/fscrypto.h
include/linux/fscrypto.h
+8
-6
未找到文件。
fs/crypto/Kconfig
浏览文件 @
56735be0
config FS_ENCRYPTION
tristate "FS Encryption (Per-file encryption)"
depends on BLOCK
select CRYPTO
select CRYPTO_AES
select CRYPTO_CBC
...
...
fs/crypto/Makefile
浏览文件 @
56735be0
obj-$(CONFIG_FS_ENCRYPTION)
+=
fscrypto.o
fscrypto-y
:=
crypto.o fname.o policy.o keyinfo.o
fscrypto-$(CONFIG_BLOCK)
+=
bio.o
fs/crypto/bio.c
0 → 100644
浏览文件 @
56735be0
/*
* This contains encryption functions for per-file encryption.
*
* Copyright (C) 2015, Google, Inc.
* Copyright (C) 2015, Motorola Mobility
*
* Written by Michael Halcrow, 2014.
*
* Filename encryption additions
* Uday Savagaonkar, 2014
* Encryption policy handling additions
* Ildar Muslukhov, 2014
* Add fscrypt_pullback_bio_page()
* Jaegeuk Kim, 2015.
*
* This has not yet undergone a rigorous security audit.
*
* The usage of AES-XTS should conform to recommendations in NIST
* Special Publication 800-38E and IEEE P1619/D16.
*/
#include <linux/pagemap.h>
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/namei.h>
#include "fscrypt_private.h"
/*
* Call fscrypt_decrypt_page on every single page, reusing the encryption
* context.
*/
static
void
completion_pages
(
struct
work_struct
*
work
)
{
struct
fscrypt_ctx
*
ctx
=
container_of
(
work
,
struct
fscrypt_ctx
,
r
.
work
);
struct
bio
*
bio
=
ctx
->
r
.
bio
;
struct
bio_vec
*
bv
;
int
i
;
bio_for_each_segment_all
(
bv
,
bio
,
i
)
{
struct
page
*
page
=
bv
->
bv_page
;
int
ret
=
fscrypt_decrypt_page
(
page
->
mapping
->
host
,
page
,
PAGE_SIZE
,
0
,
page
->
index
);
if
(
ret
)
{
WARN_ON_ONCE
(
1
);
SetPageError
(
page
);
}
else
{
SetPageUptodate
(
page
);
}
unlock_page
(
page
);
}
fscrypt_release_ctx
(
ctx
);
bio_put
(
bio
);
}
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
ctx
,
struct
bio
*
bio
)
{
INIT_WORK
(
&
ctx
->
r
.
work
,
completion_pages
);
ctx
->
r
.
bio
=
bio
;
queue_work
(
fscrypt_read_workqueue
,
&
ctx
->
r
.
work
);
}
EXPORT_SYMBOL
(
fscrypt_decrypt_bio_pages
);
void
fscrypt_pullback_bio_page
(
struct
page
**
page
,
bool
restore
)
{
struct
fscrypt_ctx
*
ctx
;
struct
page
*
bounce_page
;
/* The bounce data pages are unmapped. */
if
((
*
page
)
->
mapping
)
return
;
/* The bounce data page is unmapped. */
bounce_page
=
*
page
;
ctx
=
(
struct
fscrypt_ctx
*
)
page_private
(
bounce_page
);
/* restore control page */
*
page
=
ctx
->
w
.
control_page
;
if
(
restore
)
fscrypt_restore_control_page
(
bounce_page
);
}
EXPORT_SYMBOL
(
fscrypt_pullback_bio_page
);
int
fscrypt_zeroout_range
(
const
struct
inode
*
inode
,
pgoff_t
lblk
,
sector_t
pblk
,
unsigned
int
len
)
{
struct
fscrypt_ctx
*
ctx
;
struct
page
*
ciphertext_page
=
NULL
;
struct
bio
*
bio
;
int
ret
,
err
=
0
;
BUG_ON
(
inode
->
i_sb
->
s_blocksize
!=
PAGE_SIZE
);
ctx
=
fscrypt_get_ctx
(
inode
,
GFP_NOFS
);
if
(
IS_ERR
(
ctx
))
return
PTR_ERR
(
ctx
);
ciphertext_page
=
fscrypt_alloc_bounce_page
(
ctx
,
GFP_NOWAIT
);
if
(
IS_ERR
(
ciphertext_page
))
{
err
=
PTR_ERR
(
ciphertext_page
);
goto
errout
;
}
while
(
len
--
)
{
err
=
fscrypt_do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk
,
ZERO_PAGE
(
0
),
ciphertext_page
,
PAGE_SIZE
,
0
,
GFP_NOFS
);
if
(
err
)
goto
errout
;
bio
=
bio_alloc
(
GFP_NOWAIT
,
1
);
if
(
!
bio
)
{
err
=
-
ENOMEM
;
goto
errout
;
}
bio
->
bi_bdev
=
inode
->
i_sb
->
s_bdev
;
bio
->
bi_iter
.
bi_sector
=
pblk
<<
(
inode
->
i_sb
->
s_blocksize_bits
-
9
);
bio_set_op_attrs
(
bio
,
REQ_OP_WRITE
,
0
);
ret
=
bio_add_page
(
bio
,
ciphertext_page
,
inode
->
i_sb
->
s_blocksize
,
0
);
if
(
ret
!=
inode
->
i_sb
->
s_blocksize
)
{
/* should never happen! */
WARN_ON
(
1
);
bio_put
(
bio
);
err
=
-
EIO
;
goto
errout
;
}
err
=
submit_bio_wait
(
bio
);
if
((
err
==
0
)
&&
bio
->
bi_error
)
err
=
-
EIO
;
bio_put
(
bio
);
if
(
err
)
goto
errout
;
lblk
++
;
pblk
++
;
}
err
=
0
;
errout:
fscrypt_release_ctx
(
ctx
);
return
err
;
}
EXPORT_SYMBOL
(
fscrypt_zeroout_range
);
fs/crypto/crypto.c
浏览文件 @
56735be0
...
...
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/ratelimit.h>
#include <linux/bio.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include "fscrypt_private.h"
...
...
@@ -44,7 +43,7 @@ static mempool_t *fscrypt_bounce_page_pool = NULL;
static
LIST_HEAD
(
fscrypt_free_ctxs
);
static
DEFINE_SPINLOCK
(
fscrypt_ctx_lock
);
st
atic
st
ruct
workqueue_struct
*
fscrypt_read_workqueue
;
struct
workqueue_struct
*
fscrypt_read_workqueue
;
static
DEFINE_MUTEX
(
fscrypt_init_mutex
);
static
struct
kmem_cache
*
fscrypt_ctx_cachep
;
...
...
@@ -141,16 +140,10 @@ static void page_crypt_complete(struct crypto_async_request *req, int res)
complete
(
&
ecr
->
completion
);
}
typedef
enum
{
FS_DECRYPT
=
0
,
FS_ENCRYPT
,
}
fscrypt_direction_t
;
static
int
do_page_crypto
(
const
struct
inode
*
inode
,
fscrypt_direction_t
rw
,
u64
lblk_num
,
struct
page
*
src_page
,
struct
page
*
dest_page
,
unsigned
int
len
,
unsigned
int
offs
,
gfp_t
gfp_flags
)
int
fscrypt_do_page_crypto
(
const
struct
inode
*
inode
,
fscrypt_direction_t
rw
,
u64
lblk_num
,
struct
page
*
src_page
,
struct
page
*
dest_page
,
unsigned
int
len
,
unsigned
int
offs
,
gfp_t
gfp_flags
)
{
struct
{
__le64
index
;
...
...
@@ -205,7 +198,8 @@ static int do_page_crypto(const struct inode *inode,
return
0
;
}
static
struct
page
*
alloc_bounce_page
(
struct
fscrypt_ctx
*
ctx
,
gfp_t
gfp_flags
)
struct
page
*
fscrypt_alloc_bounce_page
(
struct
fscrypt_ctx
*
ctx
,
gfp_t
gfp_flags
)
{
ctx
->
w
.
bounce_page
=
mempool_alloc
(
fscrypt_bounce_page_pool
,
gfp_flags
);
if
(
ctx
->
w
.
bounce_page
==
NULL
)
...
...
@@ -260,9 +254,9 @@ struct page *fscrypt_encrypt_page(const struct inode *inode,
if
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_OWN_PAGES
)
{
/* with inplace-encryption we just encrypt the page */
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk_num
,
page
,
ciphertext_page
,
len
,
offs
,
gfp_flags
);
err
=
fscrypt_do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk_num
,
page
,
ciphertext_page
,
len
,
offs
,
gfp_flags
);
if
(
err
)
return
ERR_PTR
(
err
);
...
...
@@ -276,14 +270,14 @@ struct page *fscrypt_encrypt_page(const struct inode *inode,
return
(
struct
page
*
)
ctx
;
/* The encryption operation will require a bounce page. */
ciphertext_page
=
alloc_bounce_page
(
ctx
,
gfp_flags
);
ciphertext_page
=
fscrypt_
alloc_bounce_page
(
ctx
,
gfp_flags
);
if
(
IS_ERR
(
ciphertext_page
))
goto
errout
;
ctx
->
w
.
control_page
=
page
;
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk_num
,
page
,
ciphertext_page
,
len
,
offs
,
gfp_flags
);
err
=
fscrypt_
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk_num
,
page
,
ciphertext_page
,
len
,
offs
,
gfp_flags
);
if
(
err
)
{
ciphertext_page
=
ERR_PTR
(
err
);
goto
errout
;
...
...
@@ -320,72 +314,11 @@ int fscrypt_decrypt_page(const struct inode *inode, struct page *page,
if
(
!
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_OWN_PAGES
))
BUG_ON
(
!
PageLocked
(
page
));
return
do_page_crypto
(
inode
,
FS_DECRYPT
,
lblk_num
,
page
,
page
,
len
,
offs
,
GFP_NOFS
);
return
fscrypt_do_page_crypto
(
inode
,
FS_DECRYPT
,
lblk_num
,
page
,
page
,
len
,
offs
,
GFP_NOFS
);
}
EXPORT_SYMBOL
(
fscrypt_decrypt_page
);
int
fscrypt_zeroout_range
(
const
struct
inode
*
inode
,
pgoff_t
lblk
,
sector_t
pblk
,
unsigned
int
len
)
{
struct
fscrypt_ctx
*
ctx
;
struct
page
*
ciphertext_page
=
NULL
;
struct
bio
*
bio
;
int
ret
,
err
=
0
;
BUG_ON
(
inode
->
i_sb
->
s_blocksize
!=
PAGE_SIZE
);
ctx
=
fscrypt_get_ctx
(
inode
,
GFP_NOFS
);
if
(
IS_ERR
(
ctx
))
return
PTR_ERR
(
ctx
);
ciphertext_page
=
alloc_bounce_page
(
ctx
,
GFP_NOWAIT
);
if
(
IS_ERR
(
ciphertext_page
))
{
err
=
PTR_ERR
(
ciphertext_page
);
goto
errout
;
}
while
(
len
--
)
{
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk
,
ZERO_PAGE
(
0
),
ciphertext_page
,
PAGE_SIZE
,
0
,
GFP_NOFS
);
if
(
err
)
goto
errout
;
bio
=
bio_alloc
(
GFP_NOWAIT
,
1
);
if
(
!
bio
)
{
err
=
-
ENOMEM
;
goto
errout
;
}
bio
->
bi_bdev
=
inode
->
i_sb
->
s_bdev
;
bio
->
bi_iter
.
bi_sector
=
pblk
<<
(
inode
->
i_sb
->
s_blocksize_bits
-
9
);
bio_set_op_attrs
(
bio
,
REQ_OP_WRITE
,
0
);
ret
=
bio_add_page
(
bio
,
ciphertext_page
,
inode
->
i_sb
->
s_blocksize
,
0
);
if
(
ret
!=
inode
->
i_sb
->
s_blocksize
)
{
/* should never happen! */
WARN_ON
(
1
);
bio_put
(
bio
);
err
=
-
EIO
;
goto
errout
;
}
err
=
submit_bio_wait
(
bio
);
if
((
err
==
0
)
&&
bio
->
bi_error
)
err
=
-
EIO
;
bio_put
(
bio
);
if
(
err
)
goto
errout
;
lblk
++
;
pblk
++
;
}
err
=
0
;
errout:
fscrypt_release_ctx
(
ctx
);
return
err
;
}
EXPORT_SYMBOL
(
fscrypt_zeroout_range
);
/*
* Validate dentries for encrypted directories to make sure we aren't
* potentially caching stale data after a key has been added or
...
...
@@ -442,64 +375,6 @@ const struct dentry_operations fscrypt_d_ops = {
};
EXPORT_SYMBOL
(
fscrypt_d_ops
);
/*
* Call fscrypt_decrypt_page on every single page, reusing the encryption
* context.
*/
static
void
completion_pages
(
struct
work_struct
*
work
)
{
struct
fscrypt_ctx
*
ctx
=
container_of
(
work
,
struct
fscrypt_ctx
,
r
.
work
);
struct
bio
*
bio
=
ctx
->
r
.
bio
;
struct
bio_vec
*
bv
;
int
i
;
bio_for_each_segment_all
(
bv
,
bio
,
i
)
{
struct
page
*
page
=
bv
->
bv_page
;
int
ret
=
fscrypt_decrypt_page
(
page
->
mapping
->
host
,
page
,
PAGE_SIZE
,
0
,
page
->
index
);
if
(
ret
)
{
WARN_ON_ONCE
(
1
);
SetPageError
(
page
);
}
else
{
SetPageUptodate
(
page
);
}
unlock_page
(
page
);
}
fscrypt_release_ctx
(
ctx
);
bio_put
(
bio
);
}
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
ctx
,
struct
bio
*
bio
)
{
INIT_WORK
(
&
ctx
->
r
.
work
,
completion_pages
);
ctx
->
r
.
bio
=
bio
;
queue_work
(
fscrypt_read_workqueue
,
&
ctx
->
r
.
work
);
}
EXPORT_SYMBOL
(
fscrypt_decrypt_bio_pages
);
void
fscrypt_pullback_bio_page
(
struct
page
**
page
,
bool
restore
)
{
struct
fscrypt_ctx
*
ctx
;
struct
page
*
bounce_page
;
/* The bounce data pages are unmapped. */
if
((
*
page
)
->
mapping
)
return
;
/* The bounce data page is unmapped. */
bounce_page
=
*
page
;
ctx
=
(
struct
fscrypt_ctx
*
)
page_private
(
bounce_page
);
/* restore control page */
*
page
=
ctx
->
w
.
control_page
;
if
(
restore
)
fscrypt_restore_control_page
(
bounce_page
);
}
EXPORT_SYMBOL
(
fscrypt_pullback_bio_page
);
void
fscrypt_restore_control_page
(
struct
page
*
page
)
{
struct
fscrypt_ctx
*
ctx
;
...
...
fs/crypto/fname.c
浏览文件 @
56735be0
...
...
@@ -332,7 +332,7 @@ int fscrypt_fname_usr_to_disk(struct inode *inode,
* in a directory. Consequently, a user space name cannot be mapped to
* a disk-space name
*/
return
-
E
ACCES
;
return
-
E
NOKEY
;
}
EXPORT_SYMBOL
(
fscrypt_fname_usr_to_disk
);
...
...
@@ -367,7 +367,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
return
0
;
}
if
(
!
lookup
)
return
-
E
ACCES
;
return
-
E
NOKEY
;
/*
* We don't have the key and we are doing a lookup; decode the
...
...
fs/crypto/fscrypt_private.h
浏览文件 @
56735be0
...
...
@@ -71,6 +71,11 @@ struct fscrypt_info {
u8
ci_master_key
[
FS_KEY_DESCRIPTOR_SIZE
];
};
typedef
enum
{
FS_DECRYPT
=
0
,
FS_ENCRYPT
,
}
fscrypt_direction_t
;
#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
#define FS_CTX_HAS_BOUNCE_BUFFER_FL 0x00000002
...
...
@@ -85,7 +90,16 @@ struct fscrypt_completion_result {
/* crypto.c */
int
fscrypt_initialize
(
unsigned
int
cop_flags
);
extern
int
fscrypt_initialize
(
unsigned
int
cop_flags
);
extern
struct
workqueue_struct
*
fscrypt_read_workqueue
;
extern
int
fscrypt_do_page_crypto
(
const
struct
inode
*
inode
,
fscrypt_direction_t
rw
,
u64
lblk_num
,
struct
page
*
src_page
,
struct
page
*
dest_page
,
unsigned
int
len
,
unsigned
int
offs
,
gfp_t
gfp_flags
);
extern
struct
page
*
fscrypt_alloc_bounce_page
(
struct
fscrypt_ctx
*
ctx
,
gfp_t
gfp_flags
);
/* keyinfo.c */
extern
int
fscrypt_get_crypt_info
(
struct
inode
*
);
...
...
fs/crypto/keyinfo.c
浏览文件 @
56735be0
...
...
@@ -77,26 +77,22 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
static
int
validate_user_key
(
struct
fscrypt_info
*
crypt_info
,
struct
fscrypt_context
*
ctx
,
u8
*
raw_key
,
u8
*
prefix
,
int
prefix_size
)
const
char
*
prefix
)
{
u8
*
full_key_descriptor
;
char
*
description
;
struct
key
*
keyring_key
;
struct
fscrypt_key
*
master_key
;
const
struct
user_key_payload
*
ukp
;
int
full_key_len
=
prefix_size
+
(
FS_KEY_DESCRIPTOR_SIZE
*
2
)
+
1
;
int
res
;
full_key_descriptor
=
kmalloc
(
full_key_len
,
GFP_NOFS
);
if
(
!
full_key_descriptor
)
description
=
kasprintf
(
GFP_NOFS
,
"%s%*phN"
,
prefix
,
FS_KEY_DESCRIPTOR_SIZE
,
ctx
->
master_key_descriptor
);
if
(
!
description
)
return
-
ENOMEM
;
memcpy
(
full_key_descriptor
,
prefix
,
prefix_size
);
sprintf
(
full_key_descriptor
+
prefix_size
,
"%*phN"
,
FS_KEY_DESCRIPTOR_SIZE
,
ctx
->
master_key_descriptor
);
full_key_descriptor
[
full_key_len
-
1
]
=
'\0'
;
keyring_key
=
request_key
(
&
key_type_logon
,
full_key_descriptor
,
NULL
);
kfree
(
full_key_descriptor
);
keyring_key
=
request_key
(
&
key_type_logon
,
description
,
NULL
);
kfree
(
description
);
if
(
IS_ERR
(
keyring_key
))
return
PTR_ERR
(
keyring_key
);
...
...
@@ -206,12 +202,16 @@ int fscrypt_get_crypt_info(struct inode *inode)
res
=
inode
->
i_sb
->
s_cop
->
get_context
(
inode
,
&
ctx
,
sizeof
(
ctx
));
if
(
res
<
0
)
{
if
(
!
fscrypt_dummy_context_enabled
(
inode
))
if
(
!
fscrypt_dummy_context_enabled
(
inode
)
||
inode
->
i_sb
->
s_cop
->
is_encrypted
(
inode
))
return
res
;
/* Fake up a context for an unencrypted directory */
memset
(
&
ctx
,
0
,
sizeof
(
ctx
));
ctx
.
format
=
FS_ENCRYPTION_CONTEXT_FORMAT_V1
;
ctx
.
contents_encryption_mode
=
FS_ENCRYPTION_MODE_AES_256_XTS
;
ctx
.
filenames_encryption_mode
=
FS_ENCRYPTION_MODE_AES_256_CTS
;
ctx
.
flags
=
0
;
memset
(
ctx
.
master_key_descriptor
,
0x42
,
FS_KEY_DESCRIPTOR_SIZE
);
res
=
sizeof
(
ctx
);
}
else
if
(
res
!=
sizeof
(
ctx
))
{
return
-
EINVAL
;
}
...
...
@@ -247,21 +247,10 @@ int fscrypt_get_crypt_info(struct inode *inode)
if
(
!
raw_key
)
goto
out
;
if
(
fscrypt_dummy_context_enabled
(
inode
))
{
memset
(
raw_key
,
0x42
,
keysize
/
2
);
memset
(
raw_key
+
keysize
/
2
,
0x24
,
keysize
-
(
keysize
/
2
));
goto
got_key
;
}
res
=
validate_user_key
(
crypt_info
,
&
ctx
,
raw_key
,
FS_KEY_DESC_PREFIX
,
FS_KEY_DESC_PREFIX_SIZE
);
res
=
validate_user_key
(
crypt_info
,
&
ctx
,
raw_key
,
FS_KEY_DESC_PREFIX
);
if
(
res
&&
inode
->
i_sb
->
s_cop
->
key_prefix
)
{
u8
*
prefix
=
NULL
;
int
prefix_size
,
res2
;
prefix_size
=
inode
->
i_sb
->
s_cop
->
key_prefix
(
inode
,
&
prefix
);
res2
=
validate_user_key
(
crypt_info
,
&
ctx
,
raw_key
,
prefix
,
prefix_size
);
int
res2
=
validate_user_key
(
crypt_info
,
&
ctx
,
raw_key
,
inode
->
i_sb
->
s_cop
->
key_prefix
);
if
(
res2
)
{
if
(
res2
==
-
ENOKEY
)
res
=
-
ENOKEY
;
...
...
@@ -270,7 +259,6 @@ int fscrypt_get_crypt_info(struct inode *inode)
}
else
if
(
res
)
{
goto
out
;
}
got_key:
ctfm
=
crypto_alloc_skcipher
(
cipher_str
,
0
,
0
);
if
(
!
ctfm
||
IS_ERR
(
ctfm
))
{
res
=
ctfm
?
PTR_ERR
(
ctfm
)
:
-
ENOMEM
;
...
...
fs/crypto/policy.c
浏览文件 @
56735be0
...
...
@@ -13,37 +13,20 @@
#include <linux/mount.h>
#include "fscrypt_private.h"
static
int
inode_has_encryption_context
(
struct
inode
*
inode
)
{
if
(
!
inode
->
i_sb
->
s_cop
->
get_context
)
return
0
;
return
(
inode
->
i_sb
->
s_cop
->
get_context
(
inode
,
NULL
,
0L
)
>
0
);
}
/*
* check whether the policy is consistent with the encryption context
* for the inode
* check whether an encryption policy is consistent with an encryption context
*/
static
int
is_encryption_context_consistent_with_policy
(
struct
inode
*
inode
,
static
bool
is_encryption_context_consistent_with_policy
(
const
struct
fscrypt_context
*
ctx
,
const
struct
fscrypt_policy
*
policy
)
{
struct
fscrypt_context
ctx
;
int
res
;
if
(
!
inode
->
i_sb
->
s_cop
->
get_context
)
return
0
;
res
=
inode
->
i_sb
->
s_cop
->
get_context
(
inode
,
&
ctx
,
sizeof
(
ctx
));
if
(
res
!=
sizeof
(
ctx
))
return
0
;
return
(
memcmp
(
ctx
.
master_key_descriptor
,
policy
->
master_key_descriptor
,
FS_KEY_DESCRIPTOR_SIZE
)
==
0
&&
(
ctx
.
flags
==
policy
->
flags
)
&&
(
ctx
.
contents_encryption_mode
==
policy
->
contents_encryption_mode
)
&&
(
ctx
.
filenames_encryption_mode
==
policy
->
filenames_encryption_mode
));
return
memcmp
(
ctx
->
master_key_descriptor
,
policy
->
master_key_descriptor
,
FS_KEY_DESCRIPTOR_SIZE
)
==
0
&&
(
ctx
->
flags
==
policy
->
flags
)
&&
(
ctx
->
contents_encryption_mode
==
policy
->
contents_encryption_mode
)
&&
(
ctx
->
filenames_encryption_mode
==
policy
->
filenames_encryption_mode
);
}
static
int
create_encryption_context_from_policy
(
struct
inode
*
inode
,
...
...
@@ -66,20 +49,12 @@ static int create_encryption_context_from_policy(struct inode *inode,
FS_KEY_DESCRIPTOR_SIZE
);
if
(
!
fscrypt_valid_contents_enc_mode
(
policy
->
contents_encryption_mode
))
{
printk
(
KERN_WARNING
"%s: Invalid contents encryption mode %d
\n
"
,
__func__
,
policy
->
contents_encryption_mode
);
policy
->
contents_encryption_mode
))
return
-
EINVAL
;
}
if
(
!
fscrypt_valid_filenames_enc_mode
(
policy
->
filenames_encryption_mode
))
{
printk
(
KERN_WARNING
"%s: Invalid filenames encryption mode %d
\n
"
,
__func__
,
policy
->
filenames_encryption_mode
);
policy
->
filenames_encryption_mode
))
return
-
EINVAL
;
}
if
(
policy
->
flags
&
~
FS_POLICY_FLAGS_VALID
)
return
-
EINVAL
;
...
...
@@ -98,6 +73,7 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
struct
fscrypt_policy
policy
;
struct
inode
*
inode
=
file_inode
(
filp
);
int
ret
;
struct
fscrypt_context
ctx
;
if
(
copy_from_user
(
&
policy
,
arg
,
sizeof
(
policy
)))
return
-
EFAULT
;
...
...
@@ -114,9 +90,10 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
inode_lock
(
inode
);
if
(
!
inode_has_encryption_context
(
inode
))
{
ret
=
inode
->
i_sb
->
s_cop
->
get_context
(
inode
,
&
ctx
,
sizeof
(
ctx
));
if
(
ret
==
-
ENODATA
)
{
if
(
!
S_ISDIR
(
inode
->
i_mode
))
ret
=
-
E
INVAL
;
ret
=
-
E
NOTDIR
;
else
if
(
!
inode
->
i_sb
->
s_cop
->
empty_dir
)
ret
=
-
EOPNOTSUPP
;
else
if
(
!
inode
->
i_sb
->
s_cop
->
empty_dir
(
inode
))
...
...
@@ -124,12 +101,14 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
else
ret
=
create_encryption_context_from_policy
(
inode
,
&
policy
);
}
else
if
(
!
is_encryption_context_consistent_with_policy
(
inode
,
&
policy
))
{
printk
(
KERN_WARNING
"%s: Policy inconsistent with encryption context
\n
"
,
__func__
);
ret
=
-
EINVAL
;
}
else
if
(
ret
==
sizeof
(
ctx
)
&&
is_encryption_context_consistent_with_policy
(
&
ctx
,
&
policy
))
{
/* The file already uses the same encryption policy. */
ret
=
0
;
}
else
if
(
ret
>=
0
||
ret
==
-
ERANGE
)
{
/* The file already uses a different encryption policy. */
ret
=
-
EEXIST
;
}
inode_unlock
(
inode
);
...
...
@@ -151,8 +130,10 @@ int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
return
-
ENODATA
;
res
=
inode
->
i_sb
->
s_cop
->
get_context
(
inode
,
&
ctx
,
sizeof
(
ctx
));
if
(
res
<
0
&&
res
!=
-
ERANGE
)
return
res
;
if
(
res
!=
sizeof
(
ctx
))
return
-
E
NODATA
;
return
-
E
INVAL
;
if
(
ctx
.
format
!=
FS_ENCRYPTION_CONTEXT_FORMAT_V1
)
return
-
EINVAL
;
...
...
@@ -217,9 +198,9 @@ EXPORT_SYMBOL(fscrypt_has_permitted_context);
* @parent: Parent inode from which the context is inherited.
* @child: Child inode that inherits the context from @parent.
* @fs_data: private data given by FS.
* @preload: preload child i_crypt_info
* @preload: preload child i_crypt_info
if true
*
* Return:
Zero on success, non-zero otherwis
e
* Return:
0 on success, -errno on failur
e
*/
int
fscrypt_inherit_context
(
struct
inode
*
parent
,
struct
inode
*
child
,
void
*
fs_data
,
bool
preload
)
...
...
@@ -240,19 +221,11 @@ int fscrypt_inherit_context(struct inode *parent, struct inode *child,
return
-
ENOKEY
;
ctx
.
format
=
FS_ENCRYPTION_CONTEXT_FORMAT_V1
;
if
(
fscrypt_dummy_context_enabled
(
parent
))
{
ctx
.
contents_encryption_mode
=
FS_ENCRYPTION_MODE_AES_256_XTS
;
ctx
.
filenames_encryption_mode
=
FS_ENCRYPTION_MODE_AES_256_CTS
;
ctx
.
flags
=
0
;
memset
(
ctx
.
master_key_descriptor
,
0x42
,
FS_KEY_DESCRIPTOR_SIZE
);
res
=
0
;
}
else
{
ctx
.
contents_encryption_mode
=
ci
->
ci_data_mode
;
ctx
.
filenames_encryption_mode
=
ci
->
ci_filename_mode
;
ctx
.
flags
=
ci
->
ci_flags
;
memcpy
(
ctx
.
master_key_descriptor
,
ci
->
ci_master_key
,
FS_KEY_DESCRIPTOR_SIZE
);
}
ctx
.
contents_encryption_mode
=
ci
->
ci_data_mode
;
ctx
.
filenames_encryption_mode
=
ci
->
ci_filename_mode
;
ctx
.
flags
=
ci
->
ci_flags
;
memcpy
(
ctx
.
master_key_descriptor
,
ci
->
ci_master_key
,
FS_KEY_DESCRIPTOR_SIZE
);
get_random_bytes
(
ctx
.
nonce
,
FS_KEY_DERIVATION_NONCE_SIZE
);
res
=
parent
->
i_sb
->
s_cop
->
set_context
(
child
,
&
ctx
,
sizeof
(
ctx
),
fs_data
);
...
...
fs/ext4/ext4.h
浏览文件 @
56735be0
...
...
@@ -1343,11 +1343,6 @@ struct ext4_super_block {
/* Number of quota types we support */
#define EXT4_MAXQUOTAS 3
#ifdef CONFIG_EXT4_FS_ENCRYPTION
#define EXT4_KEY_DESC_PREFIX "ext4:"
#define EXT4_KEY_DESC_PREFIX_SIZE 5
#endif
/*
* fourth extended-fs super-block data in memory
*/
...
...
@@ -1517,12 +1512,6 @@ struct ext4_sb_info {
/* Barrier between changing inodes' journal flags and writepages ops. */
struct
percpu_rw_semaphore
s_journal_flag_rwsem
;
/* Encryption support */
#ifdef CONFIG_EXT4_FS_ENCRYPTION
u8
key_prefix
[
EXT4_KEY_DESC_PREFIX_SIZE
];
u8
key_prefix_size
;
#endif
};
static
inline
struct
ext4_sb_info
*
EXT4_SB
(
struct
super_block
*
sb
)
...
...
fs/ext4/ialloc.c
浏览文件 @
56735be0
...
...
@@ -771,7 +771,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
if
(
err
)
return
ERR_PTR
(
err
);
if
(
!
fscrypt_has_encryption_key
(
dir
))
return
ERR_PTR
(
-
E
PERM
);
return
ERR_PTR
(
-
E
NOKEY
);
if
(
!
handle
)
nblocks
+=
EXT4_DATA_TRANS_BLOCKS
(
dir
->
i_sb
);
encrypt
=
1
;
...
...
fs/ext4/namei.c
浏览文件 @
56735be0
...
...
@@ -1378,6 +1378,8 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
return
NULL
;
retval
=
ext4_fname_setup_filename
(
dir
,
d_name
,
1
,
&
fname
);
if
(
retval
==
-
ENOENT
)
return
NULL
;
if
(
retval
)
return
ERR_PTR
(
retval
);
...
...
@@ -3088,7 +3090,7 @@ static int ext4_symlink(struct inode *dir,
if
(
err
)
return
err
;
if
(
!
fscrypt_has_encryption_key
(
dir
))
return
-
E
PERM
;
return
-
E
NOKEY
;
disk_link
.
len
=
(
fscrypt_fname_encrypted_size
(
dir
,
len
)
+
sizeof
(
struct
fscrypt_symlink_data
));
sd
=
kzalloc
(
disk_link
.
len
,
GFP_KERNEL
);
...
...
@@ -3525,6 +3527,12 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
EXT4_I
(
old_dentry
->
d_inode
)
->
i_projid
)))
return
-
EXDEV
;
if
((
ext4_encrypted_inode
(
old_dir
)
&&
!
fscrypt_has_encryption_key
(
old_dir
))
||
(
ext4_encrypted_inode
(
new_dir
)
&&
!
fscrypt_has_encryption_key
(
new_dir
)))
return
-
ENOKEY
;
retval
=
dquot_initialize
(
old
.
dir
);
if
(
retval
)
return
retval
;
...
...
@@ -3725,6 +3733,12 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
int
retval
;
struct
timespec
ctime
;
if
((
ext4_encrypted_inode
(
old_dir
)
&&
!
fscrypt_has_encryption_key
(
old_dir
))
||
(
ext4_encrypted_inode
(
new_dir
)
&&
!
fscrypt_has_encryption_key
(
new_dir
)))
return
-
ENOKEY
;
if
((
ext4_encrypted_inode
(
old_dir
)
||
ext4_encrypted_inode
(
new_dir
))
&&
(
old_dir
!=
new_dir
)
&&
...
...
fs/ext4/super.c
浏览文件 @
56735be0
...
...
@@ -1100,12 +1100,6 @@ static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT
,
ctx
,
len
);
}
static
int
ext4_key_prefix
(
struct
inode
*
inode
,
u8
**
key
)
{
*
key
=
EXT4_SB
(
inode
->
i_sb
)
->
key_prefix
;
return
EXT4_SB
(
inode
->
i_sb
)
->
key_prefix_size
;
}
static
int
ext4_prepare_context
(
struct
inode
*
inode
)
{
return
ext4_convert_inline_data
(
inode
);
...
...
@@ -1180,8 +1174,8 @@ static unsigned ext4_max_namelen(struct inode *inode)
}
static
struct
fscrypt_operations
ext4_cryptops
=
{
.
key_prefix
=
"ext4:"
,
.
get_context
=
ext4_get_context
,
.
key_prefix
=
ext4_key_prefix
,
.
prepare_context
=
ext4_prepare_context
,
.
set_context
=
ext4_set_context
,
.
dummy_context
=
ext4_dummy_context
,
...
...
@@ -4218,11 +4212,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
ratelimit_state_init
(
&
sbi
->
s_msg_ratelimit_state
,
5
*
HZ
,
10
);
kfree
(
orig_data
);
#ifdef CONFIG_EXT4_FS_ENCRYPTION
memcpy
(
sbi
->
key_prefix
,
EXT4_KEY_DESC_PREFIX
,
EXT4_KEY_DESC_PREFIX_SIZE
);
sbi
->
key_prefix_size
=
EXT4_KEY_DESC_PREFIX_SIZE
;
#endif
return
0
;
cantfind_ext4:
...
...
fs/f2fs/dir.c
浏览文件 @
56735be0
...
...
@@ -268,7 +268,10 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
err
=
fscrypt_setup_filename
(
dir
,
child
,
1
,
&
fname
);
if
(
err
)
{
*
res_page
=
ERR_PTR
(
err
);
if
(
err
==
-
ENOENT
)
*
res_page
=
NULL
;
else
*
res_page
=
ERR_PTR
(
err
);
return
NULL
;
}
...
...
fs/f2fs/f2fs.h
浏览文件 @
56735be0
...
...
@@ -760,10 +760,6 @@ enum {
MAX_TIME
,
};
#ifdef CONFIG_F2FS_FS_ENCRYPTION
#define F2FS_KEY_DESC_PREFIX "f2fs:"
#define F2FS_KEY_DESC_PREFIX_SIZE 5
#endif
struct
f2fs_sb_info
{
struct
super_block
*
sb
;
/* pointer to VFS super block */
struct
proc_dir_entry
*
s_proc
;
/* proc entry */
...
...
@@ -771,11 +767,6 @@ struct f2fs_sb_info {
int
valid_super_block
;
/* valid super block no */
unsigned
long
s_flag
;
/* flags for sbi */
#ifdef CONFIG_F2FS_FS_ENCRYPTION
u8
key_prefix
[
F2FS_KEY_DESC_PREFIX_SIZE
];
u8
key_prefix_size
;
#endif
#ifdef CONFIG_BLK_DEV_ZONED
unsigned
int
blocks_per_blkz
;
/* F2FS blocks per zone */
unsigned
int
log_blocks_per_blkz
;
/* log2 F2FS blocks per zone */
...
...
fs/f2fs/namei.c
浏览文件 @
56735be0
...
...
@@ -403,7 +403,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
return
err
;
if
(
!
fscrypt_has_encryption_key
(
dir
))
return
-
E
PERM
;
return
-
E
NOKEY
;
disk_link
.
len
=
(
fscrypt_fname_encrypted_size
(
dir
,
len
)
+
sizeof
(
struct
fscrypt_symlink_data
));
...
...
@@ -447,7 +447,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
goto
err_out
;
if
(
!
fscrypt_has_encryption_key
(
inode
))
{
err
=
-
E
PERM
;
err
=
-
E
NOKEY
;
goto
err_out
;
}
...
...
fs/f2fs/super.c
浏览文件 @
56735be0
...
...
@@ -1156,12 +1156,6 @@ static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
ctx
,
len
,
NULL
);
}
static
int
f2fs_key_prefix
(
struct
inode
*
inode
,
u8
**
key
)
{
*
key
=
F2FS_I_SB
(
inode
)
->
key_prefix
;
return
F2FS_I_SB
(
inode
)
->
key_prefix_size
;
}
static
int
f2fs_set_context
(
struct
inode
*
inode
,
const
void
*
ctx
,
size_t
len
,
void
*
fs_data
)
{
...
...
@@ -1177,8 +1171,8 @@ static unsigned f2fs_max_namelen(struct inode *inode)
}
static
struct
fscrypt_operations
f2fs_cryptops
=
{
.
key_prefix
=
"f2fs:"
,
.
get_context
=
f2fs_get_context
,
.
key_prefix
=
f2fs_key_prefix
,
.
set_context
=
f2fs_set_context
,
.
is_encrypted
=
f2fs_encrypted_inode
,
.
empty_dir
=
f2fs_empty_dir
,
...
...
@@ -1518,12 +1512,6 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
mutex_init
(
&
sbi
->
wio_mutex
[
NODE
]);
mutex_init
(
&
sbi
->
wio_mutex
[
DATA
]);
spin_lock_init
(
&
sbi
->
cp_lock
);
#ifdef CONFIG_F2FS_FS_ENCRYPTION
memcpy
(
sbi
->
key_prefix
,
F2FS_KEY_DESC_PREFIX
,
F2FS_KEY_DESC_PREFIX_SIZE
);
sbi
->
key_prefix_size
=
F2FS_KEY_DESC_PREFIX_SIZE
;
#endif
}
static
int
init_percpu_info
(
struct
f2fs_sb_info
*
sbi
)
...
...
fs/ubifs/crypto.c
浏览文件 @
56735be0
...
...
@@ -26,15 +26,6 @@ static unsigned int ubifs_crypt_max_namelen(struct inode *inode)
return
UBIFS_MAX_NLEN
;
}
static
int
ubifs_key_prefix
(
struct
inode
*
inode
,
u8
**
key
)
{
static
char
prefix
[]
=
"ubifs:"
;
*
key
=
prefix
;
return
sizeof
(
prefix
)
-
1
;
}
int
ubifs_encrypt
(
const
struct
inode
*
inode
,
struct
ubifs_data_node
*
dn
,
unsigned
int
in_len
,
unsigned
int
*
out_len
,
int
block
)
{
...
...
@@ -88,10 +79,10 @@ int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
struct
fscrypt_operations
ubifs_crypt_operations
=
{
.
flags
=
FS_CFLG_OWN_PAGES
,
.
key_prefix
=
"ubifs:"
,
.
get_context
=
ubifs_crypt_get_context
,
.
set_context
=
ubifs_crypt_set_context
,
.
is_encrypted
=
__ubifs_crypt_is_encrypted
,
.
empty_dir
=
ubifs_crypt_empty_dir
,
.
max_namelen
=
ubifs_crypt_max_namelen
,
.
key_prefix
=
ubifs_key_prefix
,
};
include/linux/fscrypto.h
浏览文件 @
56735be0
...
...
@@ -35,7 +35,6 @@ struct fscrypt_ctx {
struct
list_head
free_list
;
/* Free list */
};
u8
flags
;
/* Flags */
u8
mode
;
/* Encryption mode for tfm */
};
/**
...
...
@@ -86,8 +85,8 @@ struct fscrypt_name {
*/
struct
fscrypt_operations
{
unsigned
int
flags
;
const
char
*
key_prefix
;
int
(
*
get_context
)(
struct
inode
*
,
void
*
,
size_t
);
int
(
*
key_prefix
)(
struct
inode
*
,
u8
**
);
int
(
*
prepare_context
)(
struct
inode
*
);
int
(
*
set_context
)(
struct
inode
*
,
const
void
*
,
size_t
,
void
*
);
int
(
*
dummy_context
)(
struct
inode
*
);
...
...
@@ -174,11 +173,8 @@ extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
u64
,
gfp_t
);
extern
int
fscrypt_decrypt_page
(
const
struct
inode
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
,
u64
);
extern
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
,
struct
bio
*
);
extern
void
fscrypt_pullback_bio_page
(
struct
page
**
,
bool
);
extern
void
fscrypt_restore_control_page
(
struct
page
*
);
extern
int
fscrypt_zeroout_range
(
const
struct
inode
*
,
pgoff_t
,
sector_t
,
unsigned
int
);
/* policy.c */
extern
int
fscrypt_ioctl_set_policy
(
struct
file
*
,
const
void
__user
*
);
extern
int
fscrypt_ioctl_get_policy
(
struct
file
*
,
void
__user
*
);
...
...
@@ -201,6 +197,12 @@ extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
const
struct
fscrypt_str
*
,
struct
fscrypt_str
*
);
extern
int
fscrypt_fname_usr_to_disk
(
struct
inode
*
,
const
struct
qstr
*
,
struct
fscrypt_str
*
);
/* bio.c */
extern
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
,
struct
bio
*
);
extern
void
fscrypt_pullback_bio_page
(
struct
page
**
,
bool
);
extern
int
fscrypt_zeroout_range
(
const
struct
inode
*
,
pgoff_t
,
sector_t
,
unsigned
int
);
#endif
/* crypto.c */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录