[git commit] tftpd: support full 512-byte requests

Denys Vlasenko vda.linux at googlemail.com
Wed Sep 3 16:35:38 UTC 2014


commit: http://git.busybox.net/busybox/commit/?id=67e01fecce5547a3d3d5695f52b375d224014b54
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Some HP PA-RISC firmware always sends fixed 512-byte requests,
with trailing garbage.

function                                             old     new   delta
tftpd_main                                           578     572      -6

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/tftp.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/networking/tftp.c b/networking/tftp.c
index 630fdaf..8e3b0a2 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -119,6 +119,7 @@ struct globals {
 	struct passwd *pw;
 	/* used in tftpd_main(), a bit big for stack: */
 	char block_buf[TFTP_BLKSIZE_DEFAULT];
+	char block_buf_tail[1];
 #if ENABLE_FEATURE_TFTP_PROGRESS_BAR
 	off_t pos;
 	off_t size;
@@ -793,14 +794,16 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
 		xchroot(argv[0]);
 	}
 
-	result = recv_from_to(STDIN_FILENO, G.block_buf, sizeof(G.block_buf),
+	result = recv_from_to(STDIN_FILENO,
+			G.block_buf, sizeof(G.block_buf) + 1,
+			/* ^^^ sizeof+1 to reliably detect oversized input */
 			0 /* flags */,
 			&peer_lsa->u.sa, &our_lsa->u.sa, our_lsa->len);
 
 	error_msg = "malformed packet";
 	opcode = ntohs(*(uint16_t*)G.block_buf);
-	if (result < 4 || result >= sizeof(G.block_buf)
-	 || G.block_buf[result-1] != '\0'
+	if (result < 4 || result > sizeof(G.block_buf)
+	/*|| G.block_buf[result-1] != '\0' - bug compatibility, see below */
 	 || (IF_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */
 	     IF_GETPUT(&&)
 	     IF_FEATURE_TFTP_GET(opcode != TFTP_WRQ) /* not upload */
@@ -808,6 +811,13 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
 	) {
 		goto err;
 	}
+	/* Some HP PA-RISC firmware always sends fixed 512-byte requests,
+	 * with trailing garbage.
+	 * Support that by not requiring NUL to be the last byte (see above).
+	 * To make strXYZ() ops safe, force NUL termination:
+	 */
+	G.block_buf_tail[0] = '\0';
+
 	local_file = G.block_buf + 2;
 	if (local_file[0] == '.' || strstr(local_file, "/.")) {
 		error_msg = "dot in file name";


More information about the busybox-cvs mailing list