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

Changed files
+51 -36
fs
+21 -32
fs/crypto/fname.c
··· 39 39 static int fname_encrypt(struct inode *inode, 40 40 const struct qstr *iname, struct fscrypt_str *oname) 41 41 { 42 - u32 ciphertext_len; 43 42 struct skcipher_request *req = NULL; 44 43 DECLARE_FS_COMPLETION_RESULT(ecr); 45 44 struct fscrypt_info *ci = inode->i_crypt_info; 46 45 struct crypto_skcipher *tfm = ci->ci_ctfm; 47 46 int res = 0; 48 47 char iv[FS_CRYPTO_BLOCK_SIZE]; 49 - struct scatterlist src_sg, dst_sg; 48 + struct scatterlist sg; 50 49 int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK); 51 - char *workbuf, buf[32], *alloc_buf = NULL; 52 - unsigned lim; 50 + unsigned int lim; 51 + unsigned int cryptlen; 53 52 54 53 lim = inode->i_sb->s_cop->max_namelen(inode); 55 54 if (iname->len <= 0 || iname->len > lim) 56 55 return -EIO; 57 56 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); 57 + /* 58 + * Copy the filename to the output buffer for encrypting in-place and 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)) { 63 - workbuf = buf; 64 - } else { 65 - alloc_buf = kmalloc(ciphertext_len, GFP_NOFS); 66 - if (!alloc_buf) 67 - return -ENOMEM; 68 - workbuf = alloc_buf; 69 - } 67 + /* Initialize the IV */ 68 + memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); 70 69 71 - /* Allocate request */ 70 + /* Set up the encryption request */ 72 71 req = skcipher_request_alloc(tfm, GFP_NOFS); 73 72 if (!req) { 74 73 printk_ratelimited(KERN_ERR 75 - "%s: crypto_request_alloc() failed\n", __func__); 76 - kfree(alloc_buf); 74 + "%s: skcipher_request_alloc() failed\n", __func__); 77 75 return -ENOMEM; 78 76 } 79 77 skcipher_request_set_callback(req, 80 78 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 81 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 */ 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); 83 + /* Do the encryption */ 95 84 res = crypto_skcipher_encrypt(req); 96 85 if (res == -EINPROGRESS || res == -EBUSY) { 86 + /* Request is being completed asynchronously; wait for it */ 97 87 wait_for_completion(&ecr.completion); 98 88 res = ecr.res; 99 89 } 100 - kfree(alloc_buf); 101 90 skcipher_request_free(req); 102 91 if (res < 0) { 103 92 printk_ratelimited(KERN_ERR ··· 94 105 return res; 95 106 } 96 107 97 - oname->len = ciphertext_len; 108 + oname->len = cryptlen; 98 109 return 0; 99 110 } 100 111
+13 -3
fs/crypto/keyinfo.c
··· 185 185 struct crypto_skcipher *ctfm; 186 186 const char *cipher_str; 187 187 int keysize; 188 - u8 raw_key[FS_MAX_KEY_SIZE]; 188 + u8 *raw_key = NULL; 189 189 int res; 190 190 191 191 res = fscrypt_initialize(); ··· 238 238 if (res) 239 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 250 if (fscrypt_dummy_context_enabled(inode)) { 242 251 memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE); 243 252 goto got_key; ··· 285 276 if (res) 286 277 goto out; 287 278 288 - memzero_explicit(raw_key, sizeof(raw_key)); 279 + kzfree(raw_key); 280 + raw_key = NULL; 289 281 if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) { 290 282 put_crypt_info(crypt_info); 291 283 goto retry; ··· 297 287 if (res == -ENOKEY) 298 288 res = 0; 299 289 put_crypt_info(crypt_info); 300 - memzero_explicit(raw_key, sizeof(raw_key)); 290 + kzfree(raw_key); 301 291 return res; 302 292 } 303 293
+1
fs/ext4/ext4.h
··· 235 235 #define EXT4_MAX_BLOCK_SIZE 65536 236 236 #define EXT4_MIN_BLOCK_LOG_SIZE 10 237 237 #define EXT4_MAX_BLOCK_LOG_SIZE 16 238 + #define EXT4_MAX_CLUSTER_LOG_SIZE 30 238 239 #ifdef __KERNEL__ 239 240 # define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) 240 241 #else
+16 -1
fs/ext4/super.c
··· 3565 3565 if (blocksize < EXT4_MIN_BLOCK_SIZE || 3566 3566 blocksize > EXT4_MAX_BLOCK_SIZE) { 3567 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 3577 goto failed_mount; 3570 3578 } 3571 3579 ··· 3703 3695 ext4_msg(sb, KERN_ERR, 3704 3696 "cluster size (%d) smaller than " 3705 3697 "block size (%d)", clustersize, blocksize); 3698 + goto failed_mount; 3699 + } 3700 + if (le32_to_cpu(es->s_log_cluster_size) > 3701 + (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { 3702 + ext4_msg(sb, KERN_ERR, 3703 + "Invalid log cluster size: %u", 3704 + le32_to_cpu(es->s_log_cluster_size)); 3706 3705 goto failed_mount; 3707 3706 } 3708 3707 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -