All of lore.kernel.org
 help / color / mirror / Atom feed
From: 이상호 <kudo3228@gmail.com>
To: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: 이상호 <kudo3228@gmail.com>,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH] hpfs: reject oversized indirect extended attributes
Date: Thu,  2 Jul 2026 06:50:14 +0900	[thread overview]
Message-ID: <20260701215014.821667-1-kudo3228@gmail.com> (raw)

HPFS stores the length of an indirect extended attribute as an unsigned
32-bit on-disk value.  hpfs_get_ea() exposes the selected EA length
through an int-sized output parameter, and get_indirect_ea() currently
also receives the length as an int.

That conversion is unsafe for malformed metadata.  If a crafted fnode
describes an indirect EA with length 0xffffffff, hpfs_get_ea() assigns
that value to *size as -1 and passes it to get_indirect_ea().  The
allocation then uses size + 1, which wraps to zero, while hpfs_ea_read()
receives the same negative value through an unsigned length parameter and
attempts to copy sector data into the zero-sized allocation.

Keep the indirect EA length unsigned until it has been validated.  Reject
values that cannot be represented by the existing int output parameter or
cannot be allocated together with the trailing NUL byte.  Also store the
output size only after hpfs_ea_read() succeeds, so callers never observe a
length for data that was not read.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: 이상호 <kudo3228@gmail.com>
---
 fs/hpfs/ea.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c
index 4664f9ab06ee..d23de4f9e2f5 100644
--- a/fs/hpfs/ea.c
+++ b/fs/hpfs/ea.c
@@ -7,6 +7,8 @@
  *  handling extended attributes
  */
 
+#include <linux/limits.h>
+
 #include "hpfs_fn.h"
 
 /* Remove external extended attributes. ano specifies whether a is a 
@@ -48,9 +50,14 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
 	}
 }
 
-static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
+static char *get_indirect_ea(struct super_block *s, int ano, secno a,
+			     unsigned int size, int *out_size)
 {
 	char *ret;
+	if (size > S32_MAX || (size_t)size + 1 > KMALLOC_MAX_SIZE) {
+		hpfs_error(s, "indirect EA is too large: %u", size);
+		return NULL;
+	}
 	if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
 		pr_err("out of memory for EA\n");
 		return NULL;
@@ -60,6 +67,7 @@ static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
 		return NULL;
 	}
 	ret[size] = 0;
+	*out_size = size;
 	return ret;
 }
 
@@ -138,7 +146,9 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
 	for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
 		if (!strcmp(ea->name, key)) {
 			if (ea_indirect(ea))
-				return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
+				return get_indirect_ea(s, ea_in_anode(ea),
+						       ea_sec(ea), ea_len(ea),
+						       size);
 			if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
 				pr_err("out of memory for EA\n");
 				return NULL;
@@ -164,7 +174,9 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
 			return NULL;
 		if (!strcmp(ea->name, key)) {
 			if (ea_indirect(ea))
-				return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
+				return get_indirect_ea(s, ea_in_anode(ea),
+						       ea_sec(ea), ea_len(ea),
+						       size);
 			if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
 				pr_err("out of memory for EA\n");
 				return NULL;
-- 
2.43.0

                 reply	other threads:[~2026-07-01 21:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260701215014.821667-1-kudo3228@gmail.com \
    --to=kudo3228@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikulas@artax.karlin.mff.cuni.cz \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.