mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Cc: "Claude Opus 4.6 \(1M context\)" <noreply@anthropic.com>
Subject: [PATCH 1/4] fs: tftp: prevent packet buffer overflow from long filenames
Date: Thu, 02 Apr 2026 09:21:19 +0200	[thread overview]
Message-ID: <20260402-net-tftp-buffer-overflows-v1-1-0a18aa8ea19e@pengutronix.de> (raw)
In-Reply-To: <20260402-net-tftp-buffer-overflows-v1-0-0a18aa8ea19e@pengutronix.de>

tftp_send() constructs RRQ/WRQ packets by sprintf'ing the filename and
TFTP options directly into the packet buffer with no bounds checking.
The packet buffer is PKTSIZE (1536) bytes with 42 bytes of headers,
leaving 1494 bytes of UDP payload. A filename longer than ~1418 bytes
overflows the packet buffer, corrupting adjacent heap memory.

Replace sprintf with snprintf, tracking available buffer space and
returning -ENAMETOOLONG if the packet would exceed the buffer.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
 fs/tftp.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/fs/tftp.c b/fs/tftp.c
index a454306b4b..1b15bc18e7 100644
--- a/fs/tftp.c
+++ b/fs/tftp.c
@@ -79,6 +79,10 @@
 /* allocate this number of blocks more than needed in the fifo */
 #define TFTP_EXTRA_BLOCKS	2
 
+/* Maximum UDP payload that fits in a PKTSIZE packet buffer */
+#define TFTP_MAX_UDP_PAYLOAD	(PKTSIZE - ETHER_HDR_SIZE - \
+				 sizeof(struct iphdr) - sizeof(struct udphdr))
+
 /* marker for an emtpy 'tftp_cache' */
 #define TFTP_CACHE_NO_ID	(-1)
 
@@ -218,7 +222,9 @@ static int tftp_send(struct file_priv *priv)
 
 	switch (priv->state) {
 	case STATE_RRQ:
-	case STATE_WRQ:
+	case STATE_WRQ: {
+		int room, n;
+
 		if (priv->push || priv->is_getattr)
 			/* atm, windowsize is supported only for RRQ and there
 			   is no need to request a full window when we are
@@ -235,7 +241,9 @@ static int tftp_send(struct file_priv *priv)
 		else
 			*s++ = htons(TFTP_WRQ);
 		pkt = (unsigned char *)s;
-		pkt += sprintf((unsigned char *)pkt,
+		room = TFTP_MAX_UDP_PAYLOAD - (pkt - xp);
+
+		n = snprintf(pkt, room,
 				"%s%c"
 				"octet%c"
 				"timeout%c"
@@ -250,24 +258,38 @@ static int tftp_send(struct file_priv *priv)
 				/* use only a minimal blksize for getattr
 				   operations, */
 				priv->is_getattr ? TFTP_BLOCK_SIZE : TFTP_MTU_SIZE);
-		pkt++;
+		if (n >= room)
+			return -ENAMETOOLONG;
+		pkt += n + 1;
+		room -= n + 1;
 
-		if (!priv->push)
+		if (!priv->push) {
 			/* we do not know the filesize in WRQ requests and
 			   'priv->filesize' will always be zero */
-			pkt += sprintf((unsigned char *)pkt,
+			n = snprintf(pkt, room,
 				       "tsize%c%lld%c",
 				       '\0', priv->filesize,
 				       '\0');
+			if (n >= room)
+				return -ENAMETOOLONG;
+			pkt += n;
+			room -= n;
+		}
 
-		if (window_size > 1)
-			pkt += sprintf((unsigned char *)pkt,
+		if (window_size > 1) {
+			n = snprintf(pkt, room,
 				       "windowsize%c%u%c",
 				       '\0', window_size,
 				       '\0');
+			if (n >= room)
+				return -ENAMETOOLONG;
+			pkt += n;
+			room -= n;
+		}
 
 		len = pkt - xp;
 		break;
+	}
 
 	case STATE_RDATA:
 		xp = pkt;

-- 
2.47.3




  reply	other threads:[~2026-04-02  7:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-02  7:21 [PATCH 0/4] tftp: fix buffer overflows Sascha Hauer
2026-04-02  7:21 ` Sascha Hauer [this message]
2026-04-02  7:21 ` [PATCH 2/4] fs: tftp: fix OACK option parsing bounds check Sascha Hauer
2026-04-02  7:21 ` [PATCH 3/4] fs: tftp: reject OACK with blocksize of zero Sascha Hauer
2026-04-02  7:21 ` [PATCH 4/4] fs: tftp: use bounded format for TFTP error message debug print Sascha Hauer

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=20260402-net-tftp-buffer-overflows-v1-1-0a18aa8ea19e@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=noreply@anthropic.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox