The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH v2 0/3] ecryptfs: split packet parser length fixes
@ 2026-07-15  5:20 Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 1/3] ecryptfs: pass packet set buffer size to parser Yichong Chen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Yichong Chen @ 2026-07-15  5:20 UTC (permalink / raw)
  To: ecryptfs
  Cc: Tyler Hicks, Thorsten Blum, Christian Brauner, Eric Biggers,
	Kees Cook, Andrew Morton, linux-kernel, Yichong Chen

This v2 splits the packet parser hardening into three separate fixes as
requested by Tyler Hicks:

  1. pass the actual packet set buffer size into ecryptfs_parse_packet_set()
  2. fix the tag 11 exact-fit size check
  3. reject too-small tag 70 packet bodies before size subtraction

Changes in v2:
- Split the original patch into three independent fixes.
- Dropped the unrelated trailing blank line removal in keystore.c.


Yichong Chen (3):
  ecryptfs: pass packet set buffer size to parser
  ecryptfs: fix tag 11 packet exact-fit size check
  ecryptfs: reject too-small tag 70 packets

 fs/ecryptfs/crypto.c          |  2 +-
 fs/ecryptfs/ecryptfs_kernel.h |  3 ++-
 fs/ecryptfs/keystore.c        | 31 +++++++++++++++++++++++++++----
 3 files changed, 30 insertions(+), 6 deletions(-)

-- 
2.51.0

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/3] ecryptfs: pass packet set buffer size to parser
  2026-07-15  5:20 [PATCH v2 0/3] ecryptfs: split packet parser length fixes Yichong Chen
@ 2026-07-15  5:20 ` Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 2/3] ecryptfs: fix tag 11 packet exact-fit size check Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 3/3] ecryptfs: reject too-small tag 70 packets Yichong Chen
  2 siblings, 0 replies; 4+ messages in thread
From: Yichong Chen @ 2026-07-15  5:20 UTC (permalink / raw)
  To: ecryptfs
  Cc: Tyler Hicks, Thorsten Blum, Christian Brauner, Eric Biggers,
	Kees Cook, Andrew Morton, linux-kernel, Yichong Chen

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: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
---
 fs/ecryptfs/crypto.c          |  2 +-
 fs/ecryptfs/ecryptfs_kernel.h |  3 ++-
 fs/ecryptfs/keystore.c        | 23 ++++++++++++++++++++---
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 74b02b5..e67119b 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -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;
 }
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index f4f56a9..7d2488a 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -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,
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index ebebc95..90c2b80 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1704,6 +1704,7 @@ out:
  * 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
@@ -1714,7 +1715,7 @@ out:
  * 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;
@@ -1736,7 +1737,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:
@@ -1751,12 +1756,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 "
@@ -1768,6 +1777,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]; "
@@ -1793,6 +1806,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:
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/3] ecryptfs: fix tag 11 packet exact-fit size check
  2026-07-15  5:20 [PATCH v2 0/3] ecryptfs: split packet parser length fixes Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 1/3] ecryptfs: pass packet set buffer size to parser Yichong Chen
@ 2026-07-15  5:20 ` Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 3/3] ecryptfs: reject too-small tag 70 packets Yichong Chen
  2 siblings, 0 replies; 4+ messages in thread
From: Yichong Chen @ 2026-07-15  5:20 UTC (permalink / raw)
  To: ecryptfs
  Cc: Tyler Hicks, Thorsten Blum, Christian Brauner, Eric Biggers,
	Kees Cook, Andrew Morton, linux-kernel, Yichong Chen

parse_tag_11_packet() rejects a packet when the already-consumed tag and
length bytes plus the packet body exceed the caller supplied maximum
packet size.  The check currently adds one extra byte, even though
*packet_size already includes the tag byte before the length is parsed.

Remove the extra byte so a tag 11 packet that exactly fits the available
buffer is accepted while oversized packets are still rejected.

Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
---
 fs/ecryptfs/keystore.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 90c2b80..02b5d77 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1537,7 +1537,7 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
 	}
 	(*packet_size) += length_size;
 	(*tag_11_contents_size) = (body_size - 14);
-	if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) {
+	if (unlikely((*packet_size) + body_size > max_packet_size)) {
 		printk(KERN_ERR "Packet size exceeds max\n");
 		rc = -EINVAL;
 		goto out;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/3] ecryptfs: reject too-small tag 70 packets
  2026-07-15  5:20 [PATCH v2 0/3] ecryptfs: split packet parser length fixes Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 1/3] ecryptfs: pass packet set buffer size to parser Yichong Chen
  2026-07-15  5:20 ` [PATCH v2 2/3] ecryptfs: fix tag 11 packet exact-fit size check Yichong Chen
@ 2026-07-15  5:20 ` Yichong Chen
  2 siblings, 0 replies; 4+ messages in thread
From: Yichong Chen @ 2026-07-15  5:20 UTC (permalink / raw)
  To: ecryptfs
  Cc: Tyler Hicks, Thorsten Blum, Christian Brauner, Eric Biggers,
	Kees Cook, Andrew Morton, linux-kernel, Yichong Chen

ecryptfs_parse_tag_70_packet() subtracts fixed metadata fields from the
parsed packet body size to derive the encrypted filename size.  A
malformed packet with a body smaller than those fixed fields can underflow
that size calculation.

Reject tag 70 packets before the subtraction unless the body contains the
signature, cipher code, and at least one byte of encrypted filename data.

Fixes: 9c79f34f7ee7 ("eCryptfs: Filename Encryption: Tag 70 packets")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
---
 fs/ecryptfs/keystore.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 02b5d77..a525a8c 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -894,6 +894,12 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
 		       "rc = [%d]\n", __func__, rc);
 		goto out;
 	}
+	if (s->parsed_tag_70_packet_size < (ECRYPTFS_SIG_SIZE + 2)) {
+		ecryptfs_printk(KERN_WARNING, "Invalid packet size [%zd]\n",
+				s->parsed_tag_70_packet_size);
+		rc = -EINVAL;
+		goto out;
+	}
 	s->block_aligned_filename_size = (s->parsed_tag_70_packet_size
 					  - ECRYPTFS_SIG_SIZE - 1);
 	if ((1 + s->packet_size_len + s->parsed_tag_70_packet_size)
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-15  5:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15  5:20 [PATCH v2 0/3] ecryptfs: split packet parser length fixes Yichong Chen
2026-07-15  5:20 ` [PATCH v2 1/3] ecryptfs: pass packet set buffer size to parser Yichong Chen
2026-07-15  5:20 ` [PATCH v2 2/3] ecryptfs: fix tag 11 packet exact-fit size check Yichong Chen
2026-07-15  5:20 ` [PATCH v2 3/3] ecryptfs: reject too-small tag 70 packets Yichong Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox