mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 13:23:02 -04:00
ecryptfs: pass packet set buffer size to parser
ecryptfs_parse_packet_set() receives a pointer into the file header, but
it calculates the remaining packet buffer size from PAGE_SIZE - 8. For
version 1 headers the packet set starts later in the header, so this can
overstate the available buffer.
Pass the actual packet set buffer length from the caller and calculate
per-packet limits from the remaining bytes in that buffer. Recompute the
remaining length after consuming a tag 3 packet before parsing the
following tag 11 packet.
Fixes: 237fead619 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
This commit is contained in:
committed by
Tyler Hicks
parent
779972513c
commit
2602b79c5b
@@ -1197,7 +1197,7 @@ static int ecryptfs_read_headers_virt(char *page_virt,
|
||||
} else
|
||||
set_default_header_data(crypt_stat);
|
||||
rc = ecryptfs_parse_packet_set(crypt_stat, (page_virt + offset),
|
||||
ecryptfs_dentry);
|
||||
PAGE_SIZE - offset, ecryptfs_dentry);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -580,7 +580,8 @@ int ecryptfs_generate_key_packet_set(char *dest_base,
|
||||
size_t *len, size_t max);
|
||||
int
|
||||
ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||
unsigned char *src, struct dentry *ecryptfs_dentry);
|
||||
unsigned char *src, size_t src_size,
|
||||
struct dentry *ecryptfs_dentry);
|
||||
int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
|
||||
ssize_t
|
||||
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
|
||||
|
||||
@@ -1714,6 +1714,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
|
||||
* ecryptfs_parse_packet_set
|
||||
* @crypt_stat: The cryptographic context
|
||||
* @src: Virtual address of region of memory containing the packets
|
||||
* @src_size: Size of the packet set buffer
|
||||
* @ecryptfs_dentry: The eCryptfs dentry associated with the packet set
|
||||
*
|
||||
* Get crypt_stat to have the file's session key if the requisite key
|
||||
@@ -1724,7 +1725,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
|
||||
* conditions.
|
||||
*/
|
||||
int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||
unsigned char *src,
|
||||
unsigned char *src, size_t src_size,
|
||||
struct dentry *ecryptfs_dentry)
|
||||
{
|
||||
size_t i = 0;
|
||||
@@ -1746,7 +1747,11 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||
* added the our &auth_tok_list */
|
||||
next_packet_is_auth_tok_packet = 1;
|
||||
while (next_packet_is_auth_tok_packet) {
|
||||
size_t max_packet_size = ((PAGE_SIZE - 8) - i);
|
||||
size_t max_packet_size;
|
||||
|
||||
if (i >= src_size)
|
||||
break;
|
||||
max_packet_size = src_size - i;
|
||||
|
||||
switch (src[i]) {
|
||||
case ECRYPTFS_TAG_3_PACKET_TYPE:
|
||||
@@ -1761,12 +1766,16 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||
goto out_wipe_list;
|
||||
}
|
||||
i += packet_size;
|
||||
if (i > src_size) {
|
||||
rc = -EIO;
|
||||
goto out_wipe_list;
|
||||
}
|
||||
rc = parse_tag_11_packet((unsigned char *)&src[i],
|
||||
sig_tmp_space,
|
||||
ECRYPTFS_SIG_SIZE,
|
||||
&tag_11_contents_size,
|
||||
&tag_11_packet_size,
|
||||
max_packet_size);
|
||||
src_size - i);
|
||||
if (rc) {
|
||||
ecryptfs_printk(KERN_ERR, "No valid "
|
||||
"(ecryptfs-specific) literal "
|
||||
@@ -1778,6 +1787,10 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||
goto out_wipe_list;
|
||||
}
|
||||
i += tag_11_packet_size;
|
||||
if (i > src_size) {
|
||||
rc = -EIO;
|
||||
goto out_wipe_list;
|
||||
}
|
||||
if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) {
|
||||
ecryptfs_printk(KERN_ERR, "Expected "
|
||||
"signature of size [%d]; "
|
||||
@@ -1803,6 +1816,10 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||
goto out_wipe_list;
|
||||
}
|
||||
i += packet_size;
|
||||
if (i > src_size) {
|
||||
rc = -EIO;
|
||||
goto out_wipe_list;
|
||||
}
|
||||
crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
|
||||
break;
|
||||
case ECRYPTFS_TAG_11_PACKET_TYPE:
|
||||
|
||||
Reference in New Issue
Block a user