summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@linux.vnet.ibm.com>2011-05-17 00:50:33 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-03 09:32:32 +0900
commit3e06eba936b0e872ba18649cfd34398b92b120dd (patch)
treeb20dea6762f218e8c18d061defa3805a6fadeb71
parentf2212c86b7bcd04b94fd11c34e95c102506180b4 (diff)
downloadlinux-stable-3e06eba936b0e872ba18649cfd34398b92b120dd.tar.gz
linux-stable-3e06eba936b0e872ba18649cfd34398b92b120dd.tar.bz2
linux-stable-3e06eba936b0e872ba18649cfd34398b92b120dd.zip
eCryptfs: Allow 2 scatterlist entries for encrypted filenames
commit 8d08dab786ad5cc2aca2bf870de370144b78c85a upstream. The buffers allocated while encrypting and decrypting long filenames can sometimes straddle two pages. In this situation, virt_to_scatterlist() will return -ENOMEM, causing the operation to fail and the user will get scary error messages in their logs: kernel: ecryptfs_write_tag_70_packet: Internal error whilst attempting to convert filename memory to scatterlist; expected rc = 1; got rc = [-12]. block_aligned_filename_size = [272] kernel: ecryptfs_encrypt_filename: Error attempting to generate tag 70 packet; rc = [-12] kernel: ecryptfs_encrypt_and_encode_filename: Error attempting to encrypt filename; rc = [-12] kernel: ecryptfs_lookup: Error attempting to encrypt and encode filename; rc = [-12] The solution is to allow up to 2 scatterlist entries to be used. Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/ecryptfs/keystore.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 03e609c45012..27a7fefb83eb 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -599,8 +599,8 @@ struct ecryptfs_write_tag_70_packet_silly_stack {
struct mutex *tfm_mutex;
char *block_aligned_filename;
struct ecryptfs_auth_tok *auth_tok;
- struct scatterlist src_sg;
- struct scatterlist dst_sg;
+ struct scatterlist src_sg[2];
+ struct scatterlist dst_sg[2];
struct blkcipher_desc desc;
char iv[ECRYPTFS_MAX_IV_BYTES];
char hash[ECRYPTFS_TAG_70_DIGEST_SIZE];
@@ -816,23 +816,21 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
memcpy(&s->block_aligned_filename[s->num_rand_bytes], filename,
filename_size);
rc = virt_to_scatterlist(s->block_aligned_filename,
- s->block_aligned_filename_size, &s->src_sg, 1);
- if (rc != 1) {
+ s->block_aligned_filename_size, s->src_sg, 2);
+ if (rc < 1) {
printk(KERN_ERR "%s: Internal error whilst attempting to "
- "convert filename memory to scatterlist; "
- "expected rc = 1; got rc = [%d]. "
+ "convert filename memory to scatterlist; rc = [%d]. "
"block_aligned_filename_size = [%zd]\n", __func__, rc,
s->block_aligned_filename_size);
goto out_release_free_unlock;
}
rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size,
- &s->dst_sg, 1);
- if (rc != 1) {
+ s->dst_sg, 2);
+ if (rc < 1) {
printk(KERN_ERR "%s: Internal error whilst attempting to "
"convert encrypted filename memory to scatterlist; "
- "expected rc = 1; got rc = [%d]. "
- "block_aligned_filename_size = [%zd]\n", __func__, rc,
- s->block_aligned_filename_size);
+ "rc = [%d]. block_aligned_filename_size = [%zd]\n",
+ __func__, rc, s->block_aligned_filename_size);
goto out_release_free_unlock;
}
/* The characters in the first block effectively do the job
@@ -855,7 +853,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
mount_crypt_stat->global_default_fn_cipher_key_bytes);
goto out_release_free_unlock;
}
- rc = crypto_blkcipher_encrypt_iv(&s->desc, &s->dst_sg, &s->src_sg,
+ rc = crypto_blkcipher_encrypt_iv(&s->desc, s->dst_sg, s->src_sg,
s->block_aligned_filename_size);
if (rc) {
printk(KERN_ERR "%s: Error attempting to encrypt filename; "
@@ -891,8 +889,8 @@ struct ecryptfs_parse_tag_70_packet_silly_stack {
struct mutex *tfm_mutex;
char *decrypted_filename;
struct ecryptfs_auth_tok *auth_tok;
- struct scatterlist src_sg;
- struct scatterlist dst_sg;
+ struct scatterlist src_sg[2];
+ struct scatterlist dst_sg[2];
struct blkcipher_desc desc;
char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1];
char iv[ECRYPTFS_MAX_IV_BYTES];
@@ -1008,13 +1006,12 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
}
mutex_lock(s->tfm_mutex);
rc = virt_to_scatterlist(&data[(*packet_size)],
- s->block_aligned_filename_size, &s->src_sg, 1);
- if (rc != 1) {
+ s->block_aligned_filename_size, s->src_sg, 2);
+ if (rc < 1) {
printk(KERN_ERR "%s: Internal error whilst attempting to "
"convert encrypted filename memory to scatterlist; "
- "expected rc = 1; got rc = [%d]. "
- "block_aligned_filename_size = [%zd]\n", __func__, rc,
- s->block_aligned_filename_size);
+ "rc = [%d]. block_aligned_filename_size = [%zd]\n",
+ __func__, rc, s->block_aligned_filename_size);
goto out_unlock;
}
(*packet_size) += s->block_aligned_filename_size;
@@ -1028,13 +1025,12 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
goto out_unlock;
}
rc = virt_to_scatterlist(s->decrypted_filename,
- s->block_aligned_filename_size, &s->dst_sg, 1);
- if (rc != 1) {
+ s->block_aligned_filename_size, s->dst_sg, 2);
+ if (rc < 1) {
printk(KERN_ERR "%s: Internal error whilst attempting to "
"convert decrypted filename memory to scatterlist; "
- "expected rc = 1; got rc = [%d]. "
- "block_aligned_filename_size = [%zd]\n", __func__, rc,
- s->block_aligned_filename_size);
+ "rc = [%d]. block_aligned_filename_size = [%zd]\n",
+ __func__, rc, s->block_aligned_filename_size);
goto out_free_unlock;
}
/* The characters in the first block effectively do the job of
@@ -1065,7 +1061,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
mount_crypt_stat->global_default_fn_cipher_key_bytes);
goto out_free_unlock;
}
- rc = crypto_blkcipher_decrypt_iv(&s->desc, &s->dst_sg, &s->src_sg,
+ rc = crypto_blkcipher_decrypt_iv(&s->desc, s->dst_sg, s->src_sg,
s->block_aligned_filename_size);
if (rc) {
printk(KERN_ERR "%s: Error attempting to decrypt filename; "