Skip to content

Commit

Permalink
eCryptfs: Allow 2 scatterlist entries for encrypted filenames
Browse files Browse the repository at this point in the history
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>
Cc: <stable@kernel.org>
  • Loading branch information
Tyler Hicks committed May 27, 2011
1 parent 0785055 commit 8d08dab
Showing 1 changed file with 21 additions and 25 deletions.
46 changes: 21 additions & 25 deletions fs/ecryptfs/keystore.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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
Expand All @@ -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; "
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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; "
Expand Down

0 comments on commit 8d08dab

Please sign in to comment.