Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 May 2026 09:03:48 +0000
From:      Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 2d9d04064354 - stable/14 - tftpd: Add missing bounds checks
Message-ID:  <6a16b374.25578.26e12173@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/14 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=2d9d0406435446ecffaab9c2908b3506ce709b8b

commit 2d9d0406435446ecffaab9c2908b3506ce709b8b
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-05-22 17:57:31 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-05-27 09:03:30 +0000

    tftpd: Add missing bounds checks
    
    In send_[rw]rq(), we were using strlcpy() to avoid overflowing our
    packet buffer, then failing to check the result and blithely advancing
    our pointer by the full length.
    
    Luckily, this code is only ever used by tftp(1), not tftpd(8).
    
    MFC after:      1 week
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D57075
    
    (cherry picked from commit 933893771344e1647eeda152016b938fdc30ccdc)
---
 libexec/tftpd/tftp-io.c | 62 +++++++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/libexec/tftpd/tftp-io.c b/libexec/tftpd/tftp-io.c
index aaacc9dd7f45..8a560cbb76b0 100644
--- a/libexec/tftpd/tftp-io.c
+++ b/libexec/tftpd/tftp-io.c
@@ -174,11 +174,11 @@ send_error(int peer, int error)
 int
 send_wrq(int peer, char *filename, char *mode)
 {
-	int n;
+	char buf[MAXPKTSIZE];
 	struct tftphdr *tp;
 	char *bp;
-	char buf[MAXPKTSIZE];
-	int size;
+	size_t len;
+	int n, size;
 
 	if (debug & DEBUG_PACKETS)
 		tftp_log(LOG_DEBUG, "Sending WRQ: filename: '%s', mode '%s'",
@@ -192,17 +192,17 @@ send_wrq(int peer, char *filename, char *mode)
 	size = offsetof(struct tftphdr, th_stuff);
 
 	bp = tp->th_stuff;
-	strlcpy(bp, filename, sizeof(buf) - size);
-	bp += strlen(filename);
-	*bp = 0;
-	bp++;
-	size += strlen(filename) + 1;
-
-	strlcpy(bp, mode, sizeof(buf) - size);
-	bp += strlen(mode);
-	*bp = 0;
-	bp++;
-	size += strlen(mode) + 1;
+	len = strlcpy(bp, filename, sizeof(buf) - size);
+	if (len >= sizeof(buf) - size)
+		goto overflow;
+	bp += len + 1;
+	size += len + 1;
+
+	len = strlcpy(bp, mode, sizeof(buf) - size);
+	if (len >= sizeof(buf) - size)
+		goto overflow;
+	bp += len + 1;
+	size += len + 1;
 
 	if (options_rfc_enabled)
 		size += make_options(peer, bp, sizeof(buf) - size);
@@ -214,6 +214,9 @@ send_wrq(int peer, char *filename, char *mode)
 		return (1);
 	}
 	return (0);
+overflow:
+	tftp_log(LOG_ERR, "%s: file name too long", __func__);
+	return (1);
 }
 
 /*
@@ -222,11 +225,11 @@ send_wrq(int peer, char *filename, char *mode)
 int
 send_rrq(int peer, char *filename, char *mode)
 {
-	int n;
+	char buf[MAXPKTSIZE];
 	struct tftphdr *tp;
 	char *bp;
-	char buf[MAXPKTSIZE];
-	int size;
+	size_t len;
+	int n, size;
 
 	if (debug & DEBUG_PACKETS)
 		tftp_log(LOG_DEBUG, "Sending RRQ: filename: '%s', mode '%s'",
@@ -240,17 +243,17 @@ send_rrq(int peer, char *filename, char *mode)
 	size = offsetof(struct tftphdr, th_stuff);
 
 	bp = tp->th_stuff;
-	strlcpy(bp, filename, sizeof(buf) - size);
-	bp += strlen(filename);
-	*bp = 0;
-	bp++;
-	size += strlen(filename) + 1;
-
-	strlcpy(bp, mode, sizeof(buf) - size);
-	bp += strlen(mode);
-	*bp = 0;
-	bp++;
-	size += strlen(mode) + 1;
+	len = strlcpy(bp, filename, sizeof(buf) - size);
+	if (len >= sizeof(buf) - size)
+		goto overflow;
+	bp += len + 1;
+	size += len + 1;
+
+	len = strlcpy(bp, mode, sizeof(buf) - size);
+	if (len >= sizeof(buf) - size)
+		goto overflow;
+	bp += len + 1;
+	size += len + 1;
 
 	if (options_rfc_enabled) {
 		options_set_request(OPT_TSIZE, "0");
@@ -264,6 +267,9 @@ send_rrq(int peer, char *filename, char *mode)
 		return (1);
 	}
 	return (0);
+overflow:
+	tftp_log(LOG_ERR, "%s: file name too long", __func__);
+	return (1);
 }
 
 /*


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a16b374.25578.26e12173>