Skip to content

Commit 2eee010

Browse files
committed
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "Lots of bug fixes and cleanups" * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (40 commits) ext4: remove unused variable ext4: use journal inode to determine journal overhead ext4: create function to read journal inode ext4: unmap metadata when zeroing blocks ext4: remove plugging from ext4_file_write_iter() ext4: allow unlocked direct IO when pages are cached ext4: require encryption feature for EXT4_IOC_SET_ENCRYPTION_POLICY fscrypto: use standard macros to compute length of fname ciphertext ext4: do not unnecessarily null-terminate encrypted symlink data ext4: release bh in make_indexed_dir ext4: Allow parallel DIO reads ext4: allow DAX writeback for hole punch jbd2: fix lockdep annotation in add_transaction_credits() blockgroup_lock.h: simplify definition of NR_BG_LOCKS blockgroup_lock.h: remove debris from bgl_lock_ptr() conversion fscrypto: make filename crypto functions return 0 on success fscrypto: rename completion callbacks to reflect usage fscrypto: remove unnecessary includes fscrypto: improved validation when loading inode encryption metadata ext4: fix memory leak when symlink decryption fails ...
2 parents 513a4be + 1801747 commit 2eee010

24 files changed

+533
-523
lines changed

fs/crypto/crypto.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include <linux/dcache.h>
2929
#include <linux/namei.h>
3030
#include <linux/fscrypto.h>
31-
#include <linux/ecryptfs.h>
3231

3332
static unsigned int num_prealloc_crypto_pages = 32;
3433
static unsigned int num_prealloc_crypto_ctxs = 128;
@@ -128,11 +127,11 @@ struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode, gfp_t gfp_flags)
128127
EXPORT_SYMBOL(fscrypt_get_ctx);
129128

130129
/**
131-
* fscrypt_complete() - The completion callback for page encryption
132-
* @req: The asynchronous encryption request context
133-
* @res: The result of the encryption operation
130+
* page_crypt_complete() - completion callback for page crypto
131+
* @req: The asynchronous cipher request context
132+
* @res: The result of the cipher operation
134133
*/
135-
static void fscrypt_complete(struct crypto_async_request *req, int res)
134+
static void page_crypt_complete(struct crypto_async_request *req, int res)
136135
{
137136
struct fscrypt_completion_result *ecr = req->data;
138137

@@ -170,7 +169,7 @@ static int do_page_crypto(struct inode *inode,
170169

171170
skcipher_request_set_callback(
172171
req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
173-
fscrypt_complete, &ecr);
172+
page_crypt_complete, &ecr);
174173

175174
BUILD_BUG_ON(FS_XTS_TWEAK_SIZE < sizeof(index));
176175
memcpy(xts_tweak, &index, sizeof(index));

fs/crypto/fname.c

+43-42
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,16 @@
1010
* This has not yet undergone a rigorous security audit.
1111
*/
1212

13-
#include <keys/encrypted-type.h>
14-
#include <keys/user-type.h>
1513
#include <linux/scatterlist.h>
1614
#include <linux/ratelimit.h>
1715
#include <linux/fscrypto.h>
1816

19-
static u32 size_round_up(size_t size, size_t blksize)
20-
{
21-
return ((size + blksize - 1) / blksize) * blksize;
22-
}
23-
2417
/**
25-
* dir_crypt_complete() -
18+
* fname_crypt_complete() - completion callback for filename crypto
19+
* @req: The asynchronous cipher request context
20+
* @res: The result of the cipher operation
2621
*/
27-
static void dir_crypt_complete(struct crypto_async_request *req, int res)
22+
static void fname_crypt_complete(struct crypto_async_request *req, int res)
2823
{
2924
struct fscrypt_completion_result *ecr = req->data;
3025

@@ -35,11 +30,11 @@ static void dir_crypt_complete(struct crypto_async_request *req, int res)
3530
}
3631

3732
/**
38-
* fname_encrypt() -
33+
* fname_encrypt() - encrypt a filename
3934
*
40-
* This function encrypts the input filename, and returns the length of the
41-
* ciphertext. Errors are returned as negative numbers. We trust the caller to
42-
* allocate sufficient memory to oname string.
35+
* The caller must have allocated sufficient memory for the @oname string.
36+
*
37+
* Return: 0 on success, -errno on failure
4338
*/
4439
static int fname_encrypt(struct inode *inode,
4540
const struct qstr *iname, struct fscrypt_str *oname)
@@ -60,10 +55,9 @@ static int fname_encrypt(struct inode *inode,
6055
if (iname->len <= 0 || iname->len > lim)
6156
return -EIO;
6257

63-
ciphertext_len = (iname->len < FS_CRYPTO_BLOCK_SIZE) ?
64-
FS_CRYPTO_BLOCK_SIZE : iname->len;
65-
ciphertext_len = size_round_up(ciphertext_len, padding);
66-
ciphertext_len = (ciphertext_len > lim) ? lim : ciphertext_len;
58+
ciphertext_len = max(iname->len, (u32)FS_CRYPTO_BLOCK_SIZE);
59+
ciphertext_len = round_up(ciphertext_len, padding);
60+
ciphertext_len = min(ciphertext_len, lim);
6761

6862
if (ciphertext_len <= sizeof(buf)) {
6963
workbuf = buf;
@@ -84,7 +78,7 @@ static int fname_encrypt(struct inode *inode,
8478
}
8579
skcipher_request_set_callback(req,
8680
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
87-
dir_crypt_complete, &ecr);
81+
fname_crypt_complete, &ecr);
8882

8983
/* Copy the input */
9084
memcpy(workbuf, iname->name, iname->len);
@@ -105,20 +99,22 @@ static int fname_encrypt(struct inode *inode,
10599
}
106100
kfree(alloc_buf);
107101
skcipher_request_free(req);
108-
if (res < 0)
102+
if (res < 0) {
109103
printk_ratelimited(KERN_ERR
110104
"%s: Error (error code %d)\n", __func__, res);
105+
return res;
106+
}
111107

112108
oname->len = ciphertext_len;
113-
return res;
109+
return 0;
114110
}
115111

116-
/*
117-
* fname_decrypt()
118-
* This function decrypts the input filename, and returns
119-
* the length of the plaintext.
120-
* Errors are returned as negative numbers.
121-
* We trust the caller to allocate sufficient memory to oname string.
112+
/**
113+
* fname_decrypt() - decrypt a filename
114+
*
115+
* The caller must have allocated sufficient memory for the @oname string.
116+
*
117+
* Return: 0 on success, -errno on failure
122118
*/
123119
static int fname_decrypt(struct inode *inode,
124120
const struct fscrypt_str *iname,
@@ -146,7 +142,7 @@ static int fname_decrypt(struct inode *inode,
146142
}
147143
skcipher_request_set_callback(req,
148144
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
149-
dir_crypt_complete, &ecr);
145+
fname_crypt_complete, &ecr);
150146

151147
/* Initialize IV */
152148
memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
@@ -168,7 +164,7 @@ static int fname_decrypt(struct inode *inode,
168164
}
169165

170166
oname->len = strnlen(oname->name, iname->len);
171-
return oname->len;
167+
return 0;
172168
}
173169

174170
static const char *lookup_table =
@@ -231,9 +227,8 @@ u32 fscrypt_fname_encrypted_size(struct inode *inode, u32 ilen)
231227

232228
if (ci)
233229
padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
234-
if (ilen < FS_CRYPTO_BLOCK_SIZE)
235-
ilen = FS_CRYPTO_BLOCK_SIZE;
236-
return size_round_up(ilen, padding);
230+
ilen = max(ilen, (u32)FS_CRYPTO_BLOCK_SIZE);
231+
return round_up(ilen, padding);
237232
}
238233
EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
239234

@@ -279,6 +274,10 @@ EXPORT_SYMBOL(fscrypt_fname_free_buffer);
279274
/**
280275
* fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
281276
* space
277+
*
278+
* The caller must have allocated sufficient memory for the @oname string.
279+
*
280+
* Return: 0 on success, -errno on failure
282281
*/
283282
int fscrypt_fname_disk_to_usr(struct inode *inode,
284283
u32 hash, u32 minor_hash,
@@ -287,13 +286,12 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
287286
{
288287
const struct qstr qname = FSTR_TO_QSTR(iname);
289288
char buf[24];
290-
int ret;
291289

292290
if (fscrypt_is_dot_dotdot(&qname)) {
293291
oname->name[0] = '.';
294292
oname->name[iname->len - 1] = '.';
295293
oname->len = iname->len;
296-
return oname->len;
294+
return 0;
297295
}
298296

299297
if (iname->len < FS_CRYPTO_BLOCK_SIZE)
@@ -303,9 +301,9 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
303301
return fname_decrypt(inode, iname, oname);
304302

305303
if (iname->len <= FS_FNAME_CRYPTO_DIGEST_SIZE) {
306-
ret = digest_encode(iname->name, iname->len, oname->name);
307-
oname->len = ret;
308-
return ret;
304+
oname->len = digest_encode(iname->name, iname->len,
305+
oname->name);
306+
return 0;
309307
}
310308
if (hash) {
311309
memcpy(buf, &hash, 4);
@@ -315,15 +313,18 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
315313
}
316314
memcpy(buf + 8, iname->name + iname->len - 16, 16);
317315
oname->name[0] = '_';
318-
ret = digest_encode(buf, 24, oname->name + 1);
319-
oname->len = ret + 1;
320-
return ret + 1;
316+
oname->len = 1 + digest_encode(buf, 24, oname->name + 1);
317+
return 0;
321318
}
322319
EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
323320

324321
/**
325322
* fscrypt_fname_usr_to_disk() - converts a filename from user space to disk
326323
* space
324+
*
325+
* The caller must have allocated sufficient memory for the @oname string.
326+
*
327+
* Return: 0 on success, -errno on failure
327328
*/
328329
int fscrypt_fname_usr_to_disk(struct inode *inode,
329330
const struct qstr *iname,
@@ -333,7 +334,7 @@ int fscrypt_fname_usr_to_disk(struct inode *inode,
333334
oname->name[0] = '.';
334335
oname->name[iname->len - 1] = '.';
335336
oname->len = iname->len;
336-
return oname->len;
337+
return 0;
337338
}
338339
if (inode->i_crypt_info)
339340
return fname_encrypt(inode, iname, oname);
@@ -367,10 +368,10 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
367368
if (dir->i_crypt_info) {
368369
ret = fscrypt_fname_alloc_buffer(dir, iname->len,
369370
&fname->crypto_buf);
370-
if (ret < 0)
371+
if (ret)
371372
return ret;
372373
ret = fname_encrypt(dir, iname, &fname->crypto_buf);
373-
if (ret < 0)
374+
if (ret)
374375
goto errout;
375376
fname->disk_name.name = fname->crypto_buf.name;
376377
fname->disk_name.len = fname->crypto_buf.len;

fs/crypto/keyinfo.c

+45-26
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@
88
* Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015.
99
*/
1010

11-
#include <keys/encrypted-type.h>
1211
#include <keys/user-type.h>
13-
#include <linux/random.h>
1412
#include <linux/scatterlist.h>
15-
#include <uapi/linux/keyctl.h>
1613
#include <linux/fscrypto.h>
1714

1815
static void derive_crypt_complete(struct crypto_async_request *req, int rc)
@@ -139,6 +136,38 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
139136
return res;
140137
}
141138

139+
static int determine_cipher_type(struct fscrypt_info *ci, struct inode *inode,
140+
const char **cipher_str_ret, int *keysize_ret)
141+
{
142+
if (S_ISREG(inode->i_mode)) {
143+
if (ci->ci_data_mode == FS_ENCRYPTION_MODE_AES_256_XTS) {
144+
*cipher_str_ret = "xts(aes)";
145+
*keysize_ret = FS_AES_256_XTS_KEY_SIZE;
146+
return 0;
147+
}
148+
pr_warn_once("fscrypto: unsupported contents encryption mode "
149+
"%d for inode %lu\n",
150+
ci->ci_data_mode, inode->i_ino);
151+
return -ENOKEY;
152+
}
153+
154+
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
155+
if (ci->ci_filename_mode == FS_ENCRYPTION_MODE_AES_256_CTS) {
156+
*cipher_str_ret = "cts(cbc(aes))";
157+
*keysize_ret = FS_AES_256_CTS_KEY_SIZE;
158+
return 0;
159+
}
160+
pr_warn_once("fscrypto: unsupported filenames encryption mode "
161+
"%d for inode %lu\n",
162+
ci->ci_filename_mode, inode->i_ino);
163+
return -ENOKEY;
164+
}
165+
166+
pr_warn_once("fscrypto: unsupported file type %d for inode %lu\n",
167+
(inode->i_mode & S_IFMT), inode->i_ino);
168+
return -ENOKEY;
169+
}
170+
142171
static void put_crypt_info(struct fscrypt_info *ci)
143172
{
144173
if (!ci)
@@ -155,8 +184,8 @@ int get_crypt_info(struct inode *inode)
155184
struct fscrypt_context ctx;
156185
struct crypto_skcipher *ctfm;
157186
const char *cipher_str;
187+
int keysize;
158188
u8 raw_key[FS_MAX_KEY_SIZE];
159-
u8 mode;
160189
int res;
161190

162191
res = fscrypt_initialize();
@@ -179,13 +208,19 @@ int get_crypt_info(struct inode *inode)
179208
if (res < 0) {
180209
if (!fscrypt_dummy_context_enabled(inode))
181210
return res;
211+
ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
182212
ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
183213
ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
184214
ctx.flags = 0;
185215
} else if (res != sizeof(ctx)) {
186216
return -EINVAL;
187217
}
188-
res = 0;
218+
219+
if (ctx.format != FS_ENCRYPTION_CONTEXT_FORMAT_V1)
220+
return -EINVAL;
221+
222+
if (ctx.flags & ~FS_POLICY_FLAGS_VALID)
223+
return -EINVAL;
189224

190225
crypt_info = kmem_cache_alloc(fscrypt_info_cachep, GFP_NOFS);
191226
if (!crypt_info)
@@ -198,27 +233,11 @@ int get_crypt_info(struct inode *inode)
198233
crypt_info->ci_keyring_key = NULL;
199234
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
200235
sizeof(crypt_info->ci_master_key));
201-
if (S_ISREG(inode->i_mode))
202-
mode = crypt_info->ci_data_mode;
203-
else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
204-
mode = crypt_info->ci_filename_mode;
205-
else
206-
BUG();
207-
208-
switch (mode) {
209-
case FS_ENCRYPTION_MODE_AES_256_XTS:
210-
cipher_str = "xts(aes)";
211-
break;
212-
case FS_ENCRYPTION_MODE_AES_256_CTS:
213-
cipher_str = "cts(cbc(aes))";
214-
break;
215-
default:
216-
printk_once(KERN_WARNING
217-
"%s: unsupported key mode %d (ino %u)\n",
218-
__func__, mode, (unsigned) inode->i_ino);
219-
res = -ENOKEY;
236+
237+
res = determine_cipher_type(crypt_info, inode, &cipher_str, &keysize);
238+
if (res)
220239
goto out;
221-
}
240+
222241
if (fscrypt_dummy_context_enabled(inode)) {
223242
memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE);
224243
goto got_key;
@@ -253,7 +272,7 @@ int get_crypt_info(struct inode *inode)
253272
crypt_info->ci_ctfm = ctfm;
254273
crypto_skcipher_clear_flags(ctfm, ~0);
255274
crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_REQ_WEAK_KEY);
256-
res = crypto_skcipher_setkey(ctfm, raw_key, fscrypt_key_size(mode));
275+
res = crypto_skcipher_setkey(ctfm, raw_key, keysize);
257276
if (res)
258277
goto out;
259278

fs/ext4/dir.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
260260
/* Directory is encrypted */
261261
err = fscrypt_fname_disk_to_usr(inode,
262262
0, 0, &de_name, &fstr);
263+
de_name = fstr;
263264
fstr.len = save_len;
264-
if (err < 0)
265+
if (err)
265266
goto errout;
266267
if (!dir_emit(ctx,
267-
fstr.name, err,
268+
de_name.name, de_name.len,
268269
le32_to_cpu(de->inode),
269270
get_dtype(sb, de->file_type)))
270271
goto done;
@@ -627,7 +628,7 @@ int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf,
627628
int buf_size)
628629
{
629630
struct ext4_dir_entry_2 *de;
630-
int nlen, rlen;
631+
int rlen;
631632
unsigned int offset = 0;
632633
char *top;
633634

@@ -637,7 +638,6 @@ int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf,
637638
if (ext4_check_dir_entry(dir, NULL, de, bh,
638639
buf, buf_size, offset))
639640
return -EFSCORRUPTED;
640-
nlen = EXT4_DIR_REC_LEN(de->name_len);
641641
rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
642642
de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
643643
offset += rlen;

0 commit comments

Comments
 (0)