Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6da22013
Commit
6da22013
authored
Nov 13, 2016
by
Theodore Ts'o
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fscrypt' into origin
parents
a2f6d9c4
a6e08912
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
124 additions
and
85 deletions
+124
-85
fs/crypto/crypto.c
fs/crypto/crypto.c
+51
-32
fs/crypto/fname.c
fs/crypto/fname.c
+23
-34
fs/crypto/keyinfo.c
fs/crypto/keyinfo.c
+13
-3
fs/ext4/inode.c
fs/ext4/inode.c
+5
-2
fs/ext4/page-io.c
fs/ext4/page-io.c
+2
-1
fs/f2fs/data.c
fs/f2fs/data.c
+4
-1
include/linux/fscrypto.h
include/linux/fscrypto.h
+26
-12
No files found.
fs/crypto/crypto.c
View file @
6da22013
...
@@ -88,7 +88,7 @@ EXPORT_SYMBOL(fscrypt_release_ctx);
...
@@ -88,7 +88,7 @@ EXPORT_SYMBOL(fscrypt_release_ctx);
* Return: An allocated and initialized encryption context on success; error
* Return: An allocated and initialized encryption context on success; error
* value or NULL otherwise.
* value or NULL otherwise.
*/
*/
struct
fscrypt_ctx
*
fscrypt_get_ctx
(
struct
inode
*
inode
,
gfp_t
gfp_flags
)
struct
fscrypt_ctx
*
fscrypt_get_ctx
(
const
struct
inode
*
inode
,
gfp_t
gfp_flags
)
{
{
struct
fscrypt_ctx
*
ctx
=
NULL
;
struct
fscrypt_ctx
*
ctx
=
NULL
;
struct
fscrypt_info
*
ci
=
inode
->
i_crypt_info
;
struct
fscrypt_info
*
ci
=
inode
->
i_crypt_info
;
...
@@ -146,9 +146,10 @@ typedef enum {
...
@@ -146,9 +146,10 @@ typedef enum {
FS_ENCRYPT
,
FS_ENCRYPT
,
}
fscrypt_direction_t
;
}
fscrypt_direction_t
;
static
int
do_page_crypto
(
struct
inode
*
inode
,
static
int
do_page_crypto
(
const
struct
inode
*
inode
,
fscrypt_direction_t
rw
,
pgoff_t
index
,
fscrypt_direction_t
rw
,
pgoff_t
index
,
struct
page
*
src_page
,
struct
page
*
dest_page
,
struct
page
*
src_page
,
struct
page
*
dest_page
,
unsigned
int
src_len
,
unsigned
int
src_offset
,
gfp_t
gfp_flags
)
gfp_t
gfp_flags
)
{
{
struct
{
struct
{
...
@@ -179,10 +180,10 @@ static int do_page_crypto(struct inode *inode,
...
@@ -179,10 +180,10 @@ static int do_page_crypto(struct inode *inode,
memset
(
xts_tweak
.
padding
,
0
,
sizeof
(
xts_tweak
.
padding
));
memset
(
xts_tweak
.
padding
,
0
,
sizeof
(
xts_tweak
.
padding
));
sg_init_table
(
&
dst
,
1
);
sg_init_table
(
&
dst
,
1
);
sg_set_page
(
&
dst
,
dest_page
,
PAGE_SIZE
,
0
);
sg_set_page
(
&
dst
,
dest_page
,
src_len
,
src_offset
);
sg_init_table
(
&
src
,
1
);
sg_init_table
(
&
src
,
1
);
sg_set_page
(
&
src
,
src_page
,
PAGE_SIZE
,
0
);
sg_set_page
(
&
src
,
src_page
,
src_len
,
src_offset
);
skcipher_request_set_crypt
(
req
,
&
src
,
&
dst
,
PAGE_SIZE
,
&
xts_tweak
);
skcipher_request_set_crypt
(
req
,
&
src
,
&
dst
,
src_len
,
&
xts_tweak
);
if
(
rw
==
FS_DECRYPT
)
if
(
rw
==
FS_DECRYPT
)
res
=
crypto_skcipher_decrypt
(
req
);
res
=
crypto_skcipher_decrypt
(
req
);
else
else
...
@@ -215,10 +216,15 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags)
...
@@ -215,10 +216,15 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags)
* fscypt_encrypt_page() - Encrypts a page
* fscypt_encrypt_page() - Encrypts a page
* @inode: The inode for which the encryption should take place
* @inode: The inode for which the encryption should take place
* @plaintext_page: The page to encrypt. Must be locked.
* @plaintext_page: The page to encrypt. Must be locked.
* @plaintext_len: Length of plaintext within page
* @plaintext_offset: Offset of plaintext within page
* @index: Index for encryption. This is mainly the page index, but
* but might be different for multiple calls on same page.
* @gfp_flags: The gfp flag for memory allocation
* @gfp_flags: The gfp flag for memory allocation
*
*
* Allocates a ciphertext page and encrypts plaintext_page into it using the ctx
* Encrypts plaintext_page using the ctx encryption context. If
* encryption context.
* the filesystem supports it, encryption is performed in-place, otherwise a
* new ciphertext_page is allocated and returned.
*
*
* Called on the page write path. The caller must call
* Called on the page write path. The caller must call
* fscrypt_restore_control_page() on the returned ciphertext page to
* fscrypt_restore_control_page() on the returned ciphertext page to
...
@@ -227,35 +233,44 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags)
...
@@ -227,35 +233,44 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags)
* Return: An allocated page with the encrypted content on success. Else, an
* Return: An allocated page with the encrypted content on success. Else, an
* error value or NULL.
* error value or NULL.
*/
*/
struct
page
*
fscrypt_encrypt_page
(
struct
inode
*
inode
,
struct
page
*
fscrypt_encrypt_page
(
const
struct
inode
*
inode
,
struct
page
*
plaintext_page
,
gfp_t
gfp_flags
)
struct
page
*
plaintext_page
,
unsigned
int
plaintext_len
,
unsigned
int
plaintext_offset
,
pgoff_t
index
,
gfp_t
gfp_flags
)
{
{
struct
fscrypt_ctx
*
ctx
;
struct
fscrypt_ctx
*
ctx
;
struct
page
*
ciphertext_page
=
NULL
;
struct
page
*
ciphertext_page
=
plaintext_page
;
int
err
;
int
err
;
BUG_ON
(
!
PageLocked
(
plaintext_page
)
);
BUG_ON
(
plaintext_len
%
FS_CRYPTO_BLOCK_SIZE
!=
0
);
ctx
=
fscrypt_get_ctx
(
inode
,
gfp_flags
);
ctx
=
fscrypt_get_ctx
(
inode
,
gfp_flags
);
if
(
IS_ERR
(
ctx
))
if
(
IS_ERR
(
ctx
))
return
(
struct
page
*
)
ctx
;
return
(
struct
page
*
)
ctx
;
if
(
!
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_INPLACE_ENCRYPTION
))
{
/* The encryption operation will require a bounce page. */
/* The encryption operation will require a bounce page. */
ciphertext_page
=
alloc_bounce_page
(
ctx
,
gfp_flags
);
ciphertext_page
=
alloc_bounce_page
(
ctx
,
gfp_flags
);
if
(
IS_ERR
(
ciphertext_page
))
if
(
IS_ERR
(
ciphertext_page
))
goto
errout
;
goto
errout
;
}
ctx
->
w
.
control_page
=
plaintext_page
;
ctx
->
w
.
control_page
=
plaintext_page
;
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
plaintext_page
->
index
,
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
index
,
plaintext_page
,
ciphertext_page
,
plaintext_page
,
ciphertext_page
,
plaintext_len
,
plaintext_offset
,
gfp_flags
);
gfp_flags
);
if
(
err
)
{
if
(
err
)
{
ciphertext_page
=
ERR_PTR
(
err
);
ciphertext_page
=
ERR_PTR
(
err
);
goto
errout
;
goto
errout
;
}
}
if
(
!
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_INPLACE_ENCRYPTION
))
{
SetPagePrivate
(
ciphertext_page
);
SetPagePrivate
(
ciphertext_page
);
set_page_private
(
ciphertext_page
,
(
unsigned
long
)
ctx
);
set_page_private
(
ciphertext_page
,
(
unsigned
long
)
ctx
);
lock_page
(
ciphertext_page
);
lock_page
(
ciphertext_page
);
}
return
ciphertext_page
;
return
ciphertext_page
;
errout:
errout:
...
@@ -265,8 +280,12 @@ struct page *fscrypt_encrypt_page(struct inode *inode,
...
@@ -265,8 +280,12 @@ struct page *fscrypt_encrypt_page(struct inode *inode,
EXPORT_SYMBOL
(
fscrypt_encrypt_page
);
EXPORT_SYMBOL
(
fscrypt_encrypt_page
);
/**
/**
* f2crypt_decrypt_page() - Decrypts a page in-place
* fscrypt_decrypt_page() - Decrypts a page in-place
* @inode: Encrypted inode to decrypt.
* @page: The page to decrypt. Must be locked.
* @page: The page to decrypt. Must be locked.
* @len: Number of bytes in @page to be decrypted.
* @offs: Start of data in @page.
* @index: Index for encryption.
*
*
* Decrypts page in-place using the ctx encryption context.
* Decrypts page in-place using the ctx encryption context.
*
*
...
@@ -274,16 +293,15 @@ EXPORT_SYMBOL(fscrypt_encrypt_page);
...
@@ -274,16 +293,15 @@ EXPORT_SYMBOL(fscrypt_encrypt_page);
*
*
* Return: Zero on success, non-zero otherwise.
* Return: Zero on success, non-zero otherwise.
*/
*/
int
fscrypt_decrypt_page
(
struct
page
*
page
)
int
fscrypt_decrypt_page
(
const
struct
inode
*
inode
,
struct
page
*
page
,
unsigned
int
len
,
unsigned
int
offs
,
pgoff_t
index
)
{
{
BUG_ON
(
!
PageLocked
(
page
));
return
do_page_crypto
(
inode
,
FS_DECRYPT
,
page
->
index
,
page
,
page
,
len
,
offs
,
GFP_NOFS
);
return
do_page_crypto
(
page
->
mapping
->
host
,
FS_DECRYPT
,
page
->
index
,
page
,
page
,
GFP_NOFS
);
}
}
EXPORT_SYMBOL
(
fscrypt_decrypt_page
);
EXPORT_SYMBOL
(
fscrypt_decrypt_page
);
int
fscrypt_zeroout_range
(
struct
inode
*
inode
,
pgoff_t
lblk
,
int
fscrypt_zeroout_range
(
const
struct
inode
*
inode
,
pgoff_t
lblk
,
sector_t
pblk
,
unsigned
int
len
)
sector_t
pblk
,
unsigned
int
len
)
{
{
struct
fscrypt_ctx
*
ctx
;
struct
fscrypt_ctx
*
ctx
;
...
@@ -306,7 +324,7 @@ int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk,
...
@@ -306,7 +324,7 @@ int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk,
while
(
len
--
)
{
while
(
len
--
)
{
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk
,
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk
,
ZERO_PAGE
(
0
),
ciphertext_page
,
ZERO_PAGE
(
0
),
ciphertext_page
,
GFP_NOFS
);
PAGE_SIZE
,
0
,
GFP_NOFS
);
if
(
err
)
if
(
err
)
goto
errout
;
goto
errout
;
...
@@ -414,7 +432,8 @@ static void completion_pages(struct work_struct *work)
...
@@ -414,7 +432,8 @@ static void completion_pages(struct work_struct *work)
bio_for_each_segment_all
(
bv
,
bio
,
i
)
{
bio_for_each_segment_all
(
bv
,
bio
,
i
)
{
struct
page
*
page
=
bv
->
bv_page
;
struct
page
*
page
=
bv
->
bv_page
;
int
ret
=
fscrypt_decrypt_page
(
page
);
int
ret
=
fscrypt_decrypt_page
(
page
->
mapping
->
host
,
page
,
PAGE_SIZE
,
0
,
page
->
index
);
if
(
ret
)
{
if
(
ret
)
{
WARN_ON_ONCE
(
1
);
WARN_ON_ONCE
(
1
);
...
...
fs/crypto/fname.c
View file @
6da22013
...
@@ -39,65 +39,54 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res)
...
@@ -39,65 +39,54 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res)
static
int
fname_encrypt
(
struct
inode
*
inode
,
static
int
fname_encrypt
(
struct
inode
*
inode
,
const
struct
qstr
*
iname
,
struct
fscrypt_str
*
oname
)
const
struct
qstr
*
iname
,
struct
fscrypt_str
*
oname
)
{
{
u32
ciphertext_len
;
struct
skcipher_request
*
req
=
NULL
;
struct
skcipher_request
*
req
=
NULL
;
DECLARE_FS_COMPLETION_RESULT
(
ecr
);
DECLARE_FS_COMPLETION_RESULT
(
ecr
);
struct
fscrypt_info
*
ci
=
inode
->
i_crypt_info
;
struct
fscrypt_info
*
ci
=
inode
->
i_crypt_info
;
struct
crypto_skcipher
*
tfm
=
ci
->
ci_ctfm
;
struct
crypto_skcipher
*
tfm
=
ci
->
ci_ctfm
;
int
res
=
0
;
int
res
=
0
;
char
iv
[
FS_CRYPTO_BLOCK_SIZE
];
char
iv
[
FS_CRYPTO_BLOCK_SIZE
];
struct
scatterlist
s
rc_sg
,
dst_s
g
;
struct
scatterlist
sg
;
int
padding
=
4
<<
(
ci
->
ci_flags
&
FS_POLICY_FLAGS_PAD_MASK
);
int
padding
=
4
<<
(
ci
->
ci_flags
&
FS_POLICY_FLAGS_PAD_MASK
);
char
*
workbuf
,
buf
[
32
],
*
alloc_buf
=
NULL
;
unsigned
int
lim
;
unsigned
lim
;
unsigned
int
cryptlen
;
lim
=
inode
->
i_sb
->
s_cop
->
max_namelen
(
inode
);
lim
=
inode
->
i_sb
->
s_cop
->
max_namelen
(
inode
);
if
(
iname
->
len
<=
0
||
iname
->
len
>
lim
)
if
(
iname
->
len
<=
0
||
iname
->
len
>
lim
)
return
-
EIO
;
return
-
EIO
;
ciphertext_len
=
max
(
iname
->
len
,
(
u32
)
FS_CRYPTO_BLOCK_SIZE
);
/*
ciphertext_len
=
round_up
(
ciphertext_len
,
padding
);
* Copy the filename to the output buffer for encrypting in-place and
ciphertext_len
=
min
(
ciphertext_len
,
lim
);
* pad it with the needed number of NUL bytes.
*/
cryptlen
=
max_t
(
unsigned
int
,
iname
->
len
,
FS_CRYPTO_BLOCK_SIZE
);
cryptlen
=
round_up
(
cryptlen
,
padding
);
cryptlen
=
min
(
cryptlen
,
lim
);
memcpy
(
oname
->
name
,
iname
->
name
,
iname
->
len
);
memset
(
oname
->
name
+
iname
->
len
,
0
,
cryptlen
-
iname
->
len
);
if
(
ciphertext_len
<=
sizeof
(
buf
))
{
/* Initialize the IV */
workbuf
=
buf
;
memset
(
iv
,
0
,
FS_CRYPTO_BLOCK_SIZE
);
}
else
{
alloc_buf
=
kmalloc
(
ciphertext_len
,
GFP_NOFS
);
if
(
!
alloc_buf
)
return
-
ENOMEM
;
workbuf
=
alloc_buf
;
}
/*
Allocate
request */
/*
Set up the encryption
request */
req
=
skcipher_request_alloc
(
tfm
,
GFP_NOFS
);
req
=
skcipher_request_alloc
(
tfm
,
GFP_NOFS
);
if
(
!
req
)
{
if
(
!
req
)
{
printk_ratelimited
(
KERN_ERR
printk_ratelimited
(
KERN_ERR
"%s: crypto_request_alloc() failed
\n
"
,
__func__
);
"%s: skcipher_request_alloc() failed
\n
"
,
__func__
);
kfree
(
alloc_buf
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
skcipher_request_set_callback
(
req
,
skcipher_request_set_callback
(
req
,
CRYPTO_TFM_REQ_MAY_BACKLOG
|
CRYPTO_TFM_REQ_MAY_SLEEP
,
CRYPTO_TFM_REQ_MAY_BACKLOG
|
CRYPTO_TFM_REQ_MAY_SLEEP
,
fname_crypt_complete
,
&
ecr
);
fname_crypt_complete
,
&
ecr
);
sg_init_one
(
&
sg
,
oname
->
name
,
cryptlen
);
skcipher_request_set_crypt
(
req
,
&
sg
,
&
sg
,
cryptlen
,
iv
);
/* Copy the input */
/* Do the encryption */
memcpy
(
workbuf
,
iname
->
name
,
iname
->
len
);
if
(
iname
->
len
<
ciphertext_len
)
memset
(
workbuf
+
iname
->
len
,
0
,
ciphertext_len
-
iname
->
len
);
/* Initialize IV */
memset
(
iv
,
0
,
FS_CRYPTO_BLOCK_SIZE
);
/* Create encryption request */
sg_init_one
(
&
src_sg
,
workbuf
,
ciphertext_len
);
sg_init_one
(
&
dst_sg
,
oname
->
name
,
ciphertext_len
);
skcipher_request_set_crypt
(
req
,
&
src_sg
,
&
dst_sg
,
ciphertext_len
,
iv
);
res
=
crypto_skcipher_encrypt
(
req
);
res
=
crypto_skcipher_encrypt
(
req
);
if
(
res
==
-
EINPROGRESS
||
res
==
-
EBUSY
)
{
if
(
res
==
-
EINPROGRESS
||
res
==
-
EBUSY
)
{
/* Request is being completed asynchronously; wait for it */
wait_for_completion
(
&
ecr
.
completion
);
wait_for_completion
(
&
ecr
.
completion
);
res
=
ecr
.
res
;
res
=
ecr
.
res
;
}
}
kfree
(
alloc_buf
);
skcipher_request_free
(
req
);
skcipher_request_free
(
req
);
if
(
res
<
0
)
{
if
(
res
<
0
)
{
printk_ratelimited
(
KERN_ERR
printk_ratelimited
(
KERN_ERR
...
@@ -105,7 +94,7 @@ static int fname_encrypt(struct inode *inode,
...
@@ -105,7 +94,7 @@ static int fname_encrypt(struct inode *inode,
return
res
;
return
res
;
}
}
oname
->
len
=
c
iphertext_
len
;
oname
->
len
=
c
rypt
len
;
return
0
;
return
0
;
}
}
...
@@ -220,7 +209,7 @@ static int digest_decode(const char *src, int len, char *dst)
...
@@ -220,7 +209,7 @@ static int digest_decode(const char *src, int len, char *dst)
return
cp
-
dst
;
return
cp
-
dst
;
}
}
u32
fscrypt_fname_encrypted_size
(
struct
inode
*
inode
,
u32
ilen
)
u32
fscrypt_fname_encrypted_size
(
const
struct
inode
*
inode
,
u32
ilen
)
{
{
int
padding
=
32
;
int
padding
=
32
;
struct
fscrypt_info
*
ci
=
inode
->
i_crypt_info
;
struct
fscrypt_info
*
ci
=
inode
->
i_crypt_info
;
...
@@ -238,7 +227,7 @@ EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
...
@@ -238,7 +227,7 @@ EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
* Allocates an output buffer that is sufficient for the crypto operation
* Allocates an output buffer that is sufficient for the crypto operation
* specified by the context and the direction.
* specified by the context and the direction.
*/
*/
int
fscrypt_fname_alloc_buffer
(
struct
inode
*
inode
,
int
fscrypt_fname_alloc_buffer
(
const
struct
inode
*
inode
,
u32
ilen
,
struct
fscrypt_str
*
crypto_str
)
u32
ilen
,
struct
fscrypt_str
*
crypto_str
)
{
{
unsigned
int
olen
=
fscrypt_fname_encrypted_size
(
inode
,
ilen
);
unsigned
int
olen
=
fscrypt_fname_encrypted_size
(
inode
,
ilen
);
...
...
fs/crypto/keyinfo.c
View file @
6da22013
...
@@ -185,7 +185,7 @@ int get_crypt_info(struct inode *inode)
...
@@ -185,7 +185,7 @@ int get_crypt_info(struct inode *inode)
struct
crypto_skcipher
*
ctfm
;
struct
crypto_skcipher
*
ctfm
;
const
char
*
cipher_str
;
const
char
*
cipher_str
;
int
keysize
;
int
keysize
;
u8
raw_key
[
FS_MAX_KEY_SIZE
]
;
u8
*
raw_key
=
NULL
;
int
res
;
int
res
;
res
=
fscrypt_initialize
();
res
=
fscrypt_initialize
();
...
@@ -238,6 +238,15 @@ int get_crypt_info(struct inode *inode)
...
@@ -238,6 +238,15 @@ int get_crypt_info(struct inode *inode)
if
(
res
)
if
(
res
)
goto
out
;
goto
out
;
/*
* This cannot be a stack buffer because it is passed to the scatterlist
* crypto API as part of key derivation.
*/
res
=
-
ENOMEM
;
raw_key
=
kmalloc
(
FS_MAX_KEY_SIZE
,
GFP_NOFS
);
if
(
!
raw_key
)
goto
out
;
if
(
fscrypt_dummy_context_enabled
(
inode
))
{
if
(
fscrypt_dummy_context_enabled
(
inode
))
{
memset
(
raw_key
,
0x42
,
FS_AES_256_XTS_KEY_SIZE
);
memset
(
raw_key
,
0x42
,
FS_AES_256_XTS_KEY_SIZE
);
goto
got_key
;
goto
got_key
;
...
@@ -276,7 +285,8 @@ int get_crypt_info(struct inode *inode)
...
@@ -276,7 +285,8 @@ int get_crypt_info(struct inode *inode)
if
(
res
)
if
(
res
)
goto
out
;
goto
out
;
memzero_explicit
(
raw_key
,
sizeof
(
raw_key
));
kzfree
(
raw_key
);
raw_key
=
NULL
;
if
(
cmpxchg
(
&
inode
->
i_crypt_info
,
NULL
,
crypt_info
)
!=
NULL
)
{
if
(
cmpxchg
(
&
inode
->
i_crypt_info
,
NULL
,
crypt_info
)
!=
NULL
)
{
put_crypt_info
(
crypt_info
);
put_crypt_info
(
crypt_info
);
goto
retry
;
goto
retry
;
...
@@ -287,7 +297,7 @@ int get_crypt_info(struct inode *inode)
...
@@ -287,7 +297,7 @@ int get_crypt_info(struct inode *inode)
if
(
res
==
-
ENOKEY
)
if
(
res
==
-
ENOKEY
)
res
=
0
;
res
=
0
;
put_crypt_info
(
crypt_info
);
put_crypt_info
(
crypt_info
);
memzero_explicit
(
raw_key
,
sizeof
(
raw_key
)
);
kzfree
(
raw_key
);
return
res
;
return
res
;
}
}
...
...
fs/ext4/inode.c
View file @
6da22013
...
@@ -1169,7 +1169,8 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
...
@@ -1169,7 +1169,8 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
if
(
unlikely
(
err
))
if
(
unlikely
(
err
))
page_zero_new_buffers
(
page
,
from
,
to
);
page_zero_new_buffers
(
page
,
from
,
to
);
else
if
(
decrypt
)
else
if
(
decrypt
)
err
=
fscrypt_decrypt_page
(
page
);
err
=
fscrypt_decrypt_page
(
page
->
mapping
->
host
,
page
,
PAGE_SIZE
,
0
,
page
->
index
);
return
err
;
return
err
;
}
}
#endif
#endif
...
@@ -3746,7 +3747,9 @@ static int __ext4_block_zero_page_range(handle_t *handle,
...
@@ -3746,7 +3747,9 @@ static int __ext4_block_zero_page_range(handle_t *handle,
/* We expect the key to be set. */
/* We expect the key to be set. */
BUG_ON
(
!
fscrypt_has_encryption_key
(
inode
));
BUG_ON
(
!
fscrypt_has_encryption_key
(
inode
));
BUG_ON
(
blocksize
!=
PAGE_SIZE
);
BUG_ON
(
blocksize
!=
PAGE_SIZE
);
WARN_ON_ONCE
(
fscrypt_decrypt_page
(
page
));
BUG_ON
(
!
PageLocked
(
page
));
WARN_ON_ONCE
(
fscrypt_decrypt_page
(
page
->
mapping
->
host
,
page
,
PAGE_SIZE
,
0
,
page
->
index
));
}
}
}
}
if
(
ext4_should_journal_data
(
inode
))
{
if
(
ext4_should_journal_data
(
inode
))
{
...
...
fs/ext4/page-io.c
View file @
6da22013
...
@@ -470,7 +470,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
...
@@ -470,7 +470,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
gfp_t
gfp_flags
=
GFP_NOFS
;
gfp_t
gfp_flags
=
GFP_NOFS
;
retry_encrypt:
retry_encrypt:
data_page
=
fscrypt_encrypt_page
(
inode
,
page
,
gfp_flags
);
data_page
=
fscrypt_encrypt_page
(
inode
,
page
,
PAGE_SIZE
,
0
,
page
->
index
,
gfp_flags
);
if
(
IS_ERR
(
data_page
))
{
if
(
IS_ERR
(
data_page
))
{
ret
=
PTR_ERR
(
data_page
);
ret
=
PTR_ERR
(
data_page
);
if
(
ret
==
-
ENOMEM
&&
wbc
->
sync_mode
==
WB_SYNC_ALL
)
{
if
(
ret
==
-
ENOMEM
&&
wbc
->
sync_mode
==
WB_SYNC_ALL
)
{
...
...
fs/f2fs/data.c
View file @
6da22013
...
@@ -1194,7 +1194,10 @@ int do_write_data_page(struct f2fs_io_info *fio)
...
@@ -1194,7 +1194,10 @@ int do_write_data_page(struct f2fs_io_info *fio)
f2fs_wait_on_encrypted_page_writeback
(
F2FS_I_SB
(
inode
),
f2fs_wait_on_encrypted_page_writeback
(
F2FS_I_SB
(
inode
),
fio
->
old_blkaddr
);
fio
->
old_blkaddr
);
retry_encrypt:
retry_encrypt:
BUG_ON
(
!
PageLocked
(
fio
->
page
));
fio
->
encrypted_page
=
fscrypt_encrypt_page
(
inode
,
fio
->
page
,
fio
->
encrypted_page
=
fscrypt_encrypt_page
(
inode
,
fio
->
page
,
PAGE_SIZE
,
0
,
fio
->
page
->
index
,
gfp_flags
);
gfp_flags
);
if
(
IS_ERR
(
fio
->
encrypted_page
))
{
if
(
IS_ERR
(
fio
->
encrypted_page
))
{
err
=
PTR_ERR
(
fio
->
encrypted_page
);
err
=
PTR_ERR
(
fio
->
encrypted_page
);
...
...
include/linux/fscrypto.h
View file @
6da22013
...
@@ -153,10 +153,16 @@ struct fscrypt_name {
...
@@ -153,10 +153,16 @@ struct fscrypt_name {
#define fname_name(p) ((p)->disk_name.name)
#define fname_name(p) ((p)->disk_name.name)
#define fname_len(p) ((p)->disk_name.len)
#define fname_len(p) ((p)->disk_name.len)
/*
* fscrypt superblock flags
*/
#define FS_CFLG_INPLACE_ENCRYPTION (1U << 1)
/*
/*
* crypto opertions for filesystems
* crypto opertions for filesystems
*/
*/
struct
fscrypt_operations
{
struct
fscrypt_operations
{
unsigned
int
flags
;
int
(
*
get_context
)(
struct
inode
*
,
void
*
,
size_t
);
int
(
*
get_context
)(
struct
inode
*
,
void
*
,
size_t
);
int
(
*
key_prefix
)(
struct
inode
*
,
u8
**
);
int
(
*
key_prefix
)(
struct
inode
*
,
u8
**
);
int
(
*
prepare_context
)(
struct
inode
*
);
int
(
*
prepare_context
)(
struct
inode
*
);
...
@@ -206,7 +212,7 @@ static inline struct page *fscrypt_control_page(struct page *page)
...
@@ -206,7 +212,7 @@ static inline struct page *fscrypt_control_page(struct page *page)
#endif
#endif
}
}
static
inline
int
fscrypt_has_encryption_key
(
struct
inode
*
inode
)
static
inline
int
fscrypt_has_encryption_key
(
const
struct
inode
*
inode
)
{
{
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
return
(
inode
->
i_crypt_info
!=
NULL
);
return
(
inode
->
i_crypt_info
!=
NULL
);
...
@@ -240,14 +246,17 @@ static inline void fscrypt_set_d_op(struct dentry *dentry)
...
@@ -240,14 +246,17 @@ static inline void fscrypt_set_d_op(struct dentry *dentry)
extern
struct
kmem_cache
*
fscrypt_info_cachep
;
extern
struct
kmem_cache
*
fscrypt_info_cachep
;
int
fscrypt_initialize
(
void
);
int
fscrypt_initialize
(
void
);
extern
struct
fscrypt_ctx
*
fscrypt_get_ctx
(
struct
inode
*
,
gfp_t
);
extern
struct
fscrypt_ctx
*
fscrypt_get_ctx
(
const
struct
inode
*
,
gfp_t
);
extern
void
fscrypt_release_ctx
(
struct
fscrypt_ctx
*
);
extern
void
fscrypt_release_ctx
(
struct
fscrypt_ctx
*
);
extern
struct
page
*
fscrypt_encrypt_page
(
struct
inode
*
,
struct
page
*
,
gfp_t
);
extern
struct
page
*
fscrypt_encrypt_page
(
const
struct
inode
*
,
struct
page
*
,
extern
int
fscrypt_decrypt_page
(
struct
page
*
);
unsigned
int
,
unsigned
int
,
pgoff_t
,
gfp_t
);
extern
int
fscrypt_decrypt_page
(
const
struct
inode
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
,
pgoff_t
);
extern
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
,
struct
bio
*
);
extern
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
,
struct
bio
*
);
extern
void
fscrypt_pullback_bio_page
(
struct
page
**
,
bool
);
extern
void
fscrypt_pullback_bio_page
(
struct
page
**
,
bool
);
extern
void
fscrypt_restore_control_page
(
struct
page
*
);
extern
void
fscrypt_restore_control_page
(
struct
page
*
);
extern
int
fscrypt_zeroout_range
(
struct
inode
*
,
pgoff_t
,
sector_t
,
extern
int
fscrypt_zeroout_range
(
const
struct
inode
*
,
pgoff_t
,
sector_t
,
unsigned
int
);
unsigned
int
);
/* policy.c */
/* policy.c */
extern
int
fscrypt_process_policy
(
struct
file
*
,
const
struct
fscrypt_policy
*
);
extern
int
fscrypt_process_policy
(
struct
file
*
,
const
struct
fscrypt_policy
*
);
...
@@ -264,8 +273,8 @@ extern void fscrypt_put_encryption_info(struct inode *, struct fscrypt_info *);
...
@@ -264,8 +273,8 @@ extern void fscrypt_put_encryption_info(struct inode *, struct fscrypt_info *);
extern
int
fscrypt_setup_filename
(
struct
inode
*
,
const
struct
qstr
*
,
extern
int
fscrypt_setup_filename
(
struct
inode
*
,
const
struct
qstr
*
,
int
lookup
,
struct
fscrypt_name
*
);
int
lookup
,
struct
fscrypt_name
*
);
extern
void
fscrypt_free_filename
(
struct
fscrypt_name
*
);
extern
void
fscrypt_free_filename
(
struct
fscrypt_name
*
);
extern
u32
fscrypt_fname_encrypted_size
(
struct
inode
*
,
u32
);
extern
u32
fscrypt_fname_encrypted_size
(
const
struct
inode
*
,
u32
);
extern
int
fscrypt_fname_alloc_buffer
(
struct
inode
*
,
u32
,
extern
int
fscrypt_fname_alloc_buffer
(
const
struct
inode
*
,
u32
,
struct
fscrypt_str
*
);
struct
fscrypt_str
*
);
extern
void
fscrypt_fname_free_buffer
(
struct
fscrypt_str
*
);
extern
void
fscrypt_fname_free_buffer
(
struct
fscrypt_str
*
);
extern
int
fscrypt_fname_disk_to_usr
(
struct
inode
*
,
u32
,
u32
,
extern
int
fscrypt_fname_disk_to_usr
(
struct
inode
*
,
u32
,
u32
,
...
@@ -275,7 +284,7 @@ extern int fscrypt_fname_usr_to_disk(struct inode *, const struct qstr *,
...
@@ -275,7 +284,7 @@ extern int fscrypt_fname_usr_to_disk(struct inode *, const struct qstr *,
#endif
#endif
/* crypto.c */
/* crypto.c */
static
inline
struct
fscrypt_ctx
*
fscrypt_notsupp_get_ctx
(
struct
inode
*
i
,
static
inline
struct
fscrypt_ctx
*
fscrypt_notsupp_get_ctx
(
const
struct
inode
*
i
,
gfp_t
f
)
gfp_t
f
)
{
{
return
ERR_PTR
(
-
EOPNOTSUPP
);
return
ERR_PTR
(
-
EOPNOTSUPP
);
...
@@ -286,13 +295,18 @@ static inline void fscrypt_notsupp_release_ctx(struct fscrypt_ctx *c)
...
@@ -286,13 +295,18 @@ static inline void fscrypt_notsupp_release_ctx(struct fscrypt_ctx *c)
return
;
return
;
}
}
static
inline
struct
page
*
fscrypt_notsupp_encrypt_page
(
struct
inode
*
i
,
static
inline
struct
page
*
fscrypt_notsupp_encrypt_page
(
const
struct
inode
*
i
,
struct
page
*
p
,
gfp_t
f
)
struct
page
*
p
,
unsigned
int
len
,
unsigned
int
offs
,
pgoff_t
index
,
gfp_t
f
)
{
{
return
ERR_PTR
(
-
EOPNOTSUPP
);
return
ERR_PTR
(
-
EOPNOTSUPP
);
}
}
static
inline
int
fscrypt_notsupp_decrypt_page
(
struct
page
*
p
)
static
inline
int
fscrypt_notsupp_decrypt_page
(
const
struct
inode
*
i
,
struct
page
*
p
,
unsigned
int
len
,
unsigned
int
offs
,
pgoff_t
index
)
{
{
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
...
@@ -313,7 +327,7 @@ static inline void fscrypt_notsupp_restore_control_page(struct page *p)
...
@@ -313,7 +327,7 @@ static inline void fscrypt_notsupp_restore_control_page(struct page *p)
return
;
return
;
}
}
static
inline
int
fscrypt_notsupp_zeroout_range
(
struct
inode
*
i
,
pgoff_t
p
,
static
inline
int
fscrypt_notsupp_zeroout_range
(
const
struct
inode
*
i
,
pgoff_t
p
,
sector_t
s
,
unsigned
int
f
)
sector_t
s
,
unsigned
int
f
)
{
{
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment