[PATCH] net: tftp: fix malformed option string parsing
Chencheng Zhang
charles.cc.zhang at gmail.com
Mon Mar 23 12:05:16 CET 2026
When formatting the TFTP options (tsize, blksize, windowsize), the
code previously used sprintf() with embedded null bytes (%c). Because
sprintf() returns the length excluding the terminating null byte,
subsequent sprintf() calls overwrote the required null separators.
This caused the options to be concatenated into a single malformed
string (e.g., "tsize0blksize1468") which breaks strict TFTP servers
like atftpd, causing them to reply with empty packets or drop the
connection.
Fix this by explicitly using strcpy() for the option names and manually
advancing the pointer to ensure the null bytes are preserved.
Signed-off-by: Chencheng Zhang <charles.cc.zhang at gmail.com>
---
net/tftp.c | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/net/tftp.c b/net/tftp.c
index 5f2e0a2bc06..5a8094791ab 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -355,20 +355,29 @@ static void tftp_send(void)
debug("send option \"timeout %s\"\n", (char *)pkt);
pkt += strlen((char *)pkt) + 1;
#ifdef CONFIG_TFTP_TSIZE
- pkt += sprintf((char *)pkt, "tsize%c%u%c",
- 0, net_boot_file_size, 0);
+ /* Write "tsize" + \0 */
+ strcpy((char *)pkt, "tsize");
+ pkt += 6; /* 5 chars + 1 null */
+
+ /* Write the value + \0 */
+ pkt += sprintf((char *)pkt, "%u", net_boot_file_size) + 1;
#endif
- /* try for more effic. blk size */
- pkt += sprintf((char *)pkt, "blksize%c%d%c",
- 0, tftp_block_size_option, 0);
- /* try for more effic. window size.
- * Implemented only for tftp get.
- * Don't bother sending if it's 1
- */
- if (tftp_state == STATE_SEND_RRQ && tftp_window_size_option > 1)
- pkt += sprintf((char *)pkt, "windowsize%c%d%c",
- 0, tftp_window_size_option, 0);
+ /* Write "blksize" + \0 */
+ strcpy((char *)pkt, "blksize");
+ pkt += 8; /* 7 chars + 1 null */
+
+ /* Write the value + \0 */
+ pkt += sprintf((char *)pkt, "%d", tftp_block_size_option) + 1;
+
+ if (tftp_state == STATE_SEND_RRQ && tftp_window_size_option > 1) {
+ /* Write "windowsize" + \0 */
+ strcpy((char *)pkt, "windowsize");
+ pkt += 11; /* 10 chars + 1 null */
+
+ /* Write the value + \0 */
+ pkt += sprintf((char *)pkt, "%d", tftp_window_size_option) + 1;
+ }
len = pkt - xp;
break;
--
2.34.1
More information about the U-Boot
mailing list