aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-11-19 21:33:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-11-19 21:33:50 -0500
commitd117b9acaeada0b243f31e0fe83e111fcc9a6644 (patch)
tree3ba4fefa66b461127523bef71f2472b28e6d4342 /fs
parent50d438fb9e4229cb37ec89a22c066b626e30885c (diff)
parent8cdf3372fe8368f56315e66bea9f35053c418093 (diff)
Merge tag 'ext4_for_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o: "A security fix (so a maliciously corrupted file system image won't panic the kernel) and some fixes for CONFIG_VMAP_STACK" * tag 'ext4_for_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: sanity check the block and cluster size at mount time fscrypto: don't use on-stack buffer for key derivation fscrypto: don't use on-stack buffer for filename encryption
Diffstat (limited to 'fs')
-rw-r--r--fs/crypto/fname.c53
-rw-r--r--fs/crypto/keyinfo.c16
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/super.c17
4 files changed, 51 insertions, 36 deletions
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 9a28133ac3b8..9b774f4b50c8 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -39,65 +39,54 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res)
39static int fname_encrypt(struct inode *inode, 39static int fname_encrypt(struct inode *inode,
40 const struct qstr *iname, struct fscrypt_str *oname) 40 const struct qstr *iname, struct fscrypt_str *oname)
41{ 41{
42 u32 ciphertext_len;
43 struct skcipher_request *req = NULL; 42 struct skcipher_request *req = NULL;
44 DECLARE_FS_COMPLETION_RESULT(ecr); 43 DECLARE_FS_COMPLETION_RESULT(ecr);
45 struct fscrypt_info *ci = inode->i_crypt_info; 44 struct fscrypt_info *ci = inode->i_crypt_info;
46 struct crypto_skcipher *tfm = ci->ci_ctfm; 45 struct crypto_skcipher *tfm = ci->ci_ctfm;
47 int res = 0; 46 int res = 0;
48 char iv[FS_CRYPTO_BLOCK_SIZE]; 47 char iv[FS_CRYPTO_BLOCK_SIZE];
49 struct scatterlist src_sg, dst_sg; 48 struct scatterlist sg;
50 int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK); 49 int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
51 char *workbuf, buf[32], *alloc_buf = NULL; 50 unsigned int lim;
52 unsigned lim; 51 unsigned int cryptlen;
53 52
54 lim = inode->i_sb->s_cop->max_namelen(inode); 53 lim = inode->i_sb->s_cop->max_namelen(inode);
55 if (iname->len <= 0 || iname->len > lim) 54 if (iname->len <= 0 || iname->len > lim)
56 return -EIO; 55 return -EIO;
57 56
58 ciphertext_len = max(iname->len, (u32)FS_CRYPTO_BLOCK_SIZE); 57 /*
59 ciphertext_len = round_up(ciphertext_len, padding); 58 * Copy the filename to the output buffer for encrypting in-place and
60 ciphertext_len = min(ciphertext_len, lim); 59 * pad it with the needed number of NUL bytes.
60 */
61 cryptlen = max_t(unsigned int, iname->len, FS_CRYPTO_BLOCK_SIZE);
62 cryptlen = round_up(cryptlen, padding);
63 cryptlen = min(cryptlen, lim);
64 memcpy(oname->name, iname->name, iname->len);
65 memset(oname->name + iname->len, 0, cryptlen - iname->len);
61 66
62 if (ciphertext_len <= sizeof(buf)) { 67 /* Initialize the IV */
63 workbuf = buf; 68 memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
64 } else {
65 alloc_buf = kmalloc(ciphertext_len, GFP_NOFS);
66 if (!alloc_buf)
67 return -ENOMEM;
68 workbuf = alloc_buf;
69 }
70 69
71 /* Allocate request */ 70 /* Set up the encryption request */
72 req = skcipher_request_alloc(tfm, GFP_NOFS); 71 req = skcipher_request_alloc(tfm, GFP_NOFS);
73 if (!req) { 72 if (!req) {
74 printk_ratelimited(KERN_ERR 73 printk_ratelimited(KERN_ERR
75 "%s: crypto_request_alloc() failed\n", __func__); 74 "%s: skcipher_request_alloc() failed\n", __func__);
76 kfree(alloc_buf);
77 return -ENOMEM; 75 return -ENOMEM;
78 } 76 }
79 skcipher_request_set_callback(req, 77 skcipher_request_set_callback(req,
80 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 78 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
81 fname_crypt_complete, &ecr); 79 fname_crypt_complete, &ecr);
80 sg_init_one(&sg, oname->name, cryptlen);
81 skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv);
82 82
83 /* Copy the input */ 83 /* Do the encryption */
84 memcpy(workbuf, iname->name, iname->len);
85 if (iname->len < ciphertext_len)
86 memset(workbuf + iname->len, 0, ciphertext_len - iname->len);
87
88 /* Initialize IV */
89 memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
90
91 /* Create encryption request */
92 sg_init_one(&src_sg, workbuf, ciphertext_len);
93 sg_init_one(&dst_sg, oname->name, ciphertext_len);
94 skcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv);
95 res = crypto_skcipher_encrypt(req); 84 res = crypto_skcipher_encrypt(req);
96 if (res == -EINPROGRESS || res == -EBUSY) { 85 if (res == -EINPROGRESS || res == -EBUSY) {
86 /* Request is being completed asynchronously; wait for it */
97 wait_for_completion(&ecr.completion); 87 wait_for_completion(&ecr.completion);
98 res = ecr.res; 88 res = ecr.res;
99 } 89 }
100 kfree(alloc_buf);
101 skcipher_request_free(req); 90 skcipher_request_free(req);
102 if (res < 0) { 91 if (res < 0) {
103 printk_ratelimited(KERN_ERR 92 printk_ratelimited(KERN_ERR
@@ -105,7 +94,7 @@ static int fname_encrypt(struct inode *inode,
105 return res; 94 return res;
106 } 95 }
107 96
108 oname->len = ciphertext_len; 97 oname->len = cryptlen;
109 return 0; 98 return 0;
110} 99}
111 100
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 82f0285f5d08..67fb6d8876d0 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -185,7 +185,7 @@ int get_crypt_info(struct inode *inode)
185 struct crypto_skcipher *ctfm; 185 struct crypto_skcipher *ctfm;
186 const char *cipher_str; 186 const char *cipher_str;
187 int keysize; 187 int keysize;
188 u8 raw_key[FS_MAX_KEY_SIZE]; 188 u8 *raw_key = NULL;
189 int res; 189 int res;
190 190
191 res = fscrypt_initialize(); 191 res = fscrypt_initialize();
@@ -238,6 +238,15 @@ retry:
238 if (res) 238 if (res)
239 goto out; 239 goto out;
240 240
241 /*
242 * This cannot be a stack buffer because it is passed to the scatterlist
243 * crypto API as part of key derivation.
244 */
245 res = -ENOMEM;
246 raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS);
247 if (!raw_key)
248 goto out;
249
241 if (fscrypt_dummy_context_enabled(inode)) { 250 if (fscrypt_dummy_context_enabled(inode)) {
242 memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE); 251 memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE);
243 goto got_key; 252 goto got_key;
@@ -276,7 +285,8 @@ got_key:
276 if (res) 285 if (res)
277 goto out; 286 goto out;
278 287
279 memzero_explicit(raw_key, sizeof(raw_key)); 288 kzfree(raw_key);
289 raw_key = NULL;
280 if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) { 290 if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) {
281 put_crypt_info(crypt_info); 291 put_crypt_info(crypt_info);
282 goto retry; 292 goto retry;
@@ -287,7 +297,7 @@ out:
287 if (res == -ENOKEY) 297 if (res == -ENOKEY)
288 res = 0; 298 res = 0;
289 put_crypt_info(crypt_info); 299 put_crypt_info(crypt_info);
290 memzero_explicit(raw_key, sizeof(raw_key)); 300 kzfree(raw_key);
291 return res; 301 return res;
292} 302}
293 303
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 282a51b07c57..a8a750f59621 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -235,6 +235,7 @@ struct ext4_io_submit {
235#define EXT4_MAX_BLOCK_SIZE 65536 235#define EXT4_MAX_BLOCK_SIZE 65536
236#define EXT4_MIN_BLOCK_LOG_SIZE 10 236#define EXT4_MIN_BLOCK_LOG_SIZE 10
237#define EXT4_MAX_BLOCK_LOG_SIZE 16 237#define EXT4_MAX_BLOCK_LOG_SIZE 16
238#define EXT4_MAX_CLUSTER_LOG_SIZE 30
238#ifdef __KERNEL__ 239#ifdef __KERNEL__
239# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) 240# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize)
240#else 241#else
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 20da99da0a34..52b0530c5d65 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3565,7 +3565,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3565 if (blocksize < EXT4_MIN_BLOCK_SIZE || 3565 if (blocksize < EXT4_MIN_BLOCK_SIZE ||
3566 blocksize > EXT4_MAX_BLOCK_SIZE) { 3566 blocksize > EXT4_MAX_BLOCK_SIZE) {
3567 ext4_msg(sb, KERN_ERR, 3567 ext4_msg(sb, KERN_ERR,
3568 "Unsupported filesystem blocksize %d", blocksize); 3568 "Unsupported filesystem blocksize %d (%d log_block_size)",
3569 blocksize, le32_to_cpu(es->s_log_block_size));
3570 goto failed_mount;
3571 }
3572 if (le32_to_cpu(es->s_log_block_size) >
3573 (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
3574 ext4_msg(sb, KERN_ERR,
3575 "Invalid log block size: %u",
3576 le32_to_cpu(es->s_log_block_size));
3569 goto failed_mount; 3577 goto failed_mount;
3570 } 3578 }
3571 3579
@@ -3697,6 +3705,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3697 "block size (%d)", clustersize, blocksize); 3705 "block size (%d)", clustersize, blocksize);
3698 goto failed_mount; 3706 goto failed_mount;
3699 } 3707 }
3708 if (le32_to_cpu(es->s_log_cluster_size) >
3709 (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
3710 ext4_msg(sb, KERN_ERR,
3711 "Invalid log cluster size: %u",
3712 le32_to_cpu(es->s_log_cluster_size));
3713 goto failed_mount;
3714 }
3700 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - 3715 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
3701 le32_to_cpu(es->s_log_block_size); 3716 le32_to_cpu(es->s_log_block_size);
3702 sbi->s_clusters_per_group = 3717 sbi->s_clusters_per_group =