git: 9f9544fd92e6 - main - tftp: Fix buffer overflow and fd leak in multi-file PUT.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Thu, 17 Nov 2022 16:41:30 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=9f9544fd92e606d13e228b713d3c4a7cad78575d

commit 9f9544fd92e606d13e228b713d3c4a7cad78575d
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2022-11-17 16:15:04 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2022-11-17 16:26:24 +0000

    tftp: Fix buffer overflow and fd leak in multi-file PUT.
    
    Sponsored by:   Klara, Inc.
    Differential Revision: https://reviews.freebsd.org/D37422
---
 usr.bin/tftp/main.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/usr.bin/tftp/main.c b/usr.bin/tftp/main.c
index 33546dc4ee23..b6d7bd2a0dcc 100644
--- a/usr.bin/tftp/main.c
+++ b/usr.bin/tftp/main.c
@@ -445,7 +445,7 @@ put(int argc, char *argv[])
 {
 	int	fd;
 	int	n;
-	char	*cp, *targ;
+	char	*cp, *targ, *path;
 	char	line[MAXLINE];
 	struct stat sb;
 
@@ -507,26 +507,32 @@ put(int argc, char *argv[])
 	}
 				/* this assumes the target is a directory */
 				/* on a remote unix system.  hmmmm.  */
-	cp = strchr(targ, '\0');
-	*cp++ = '/';
 	for (n = 1; n < argc - 1; n++) {
-		strcpy(cp, tail(argv[n]));
+		if (asprintf(&path, "%s/%s", targ, tail(argv[n])) < 0)
+			err(1, "malloc");
+
 		fd = open(argv[n], O_RDONLY);
 		if (fd < 0) {
 			warn("%s", argv[n]);
+			free(path);
 			continue;
 		}
 
 		if (fstat(fd, &sb) < 0) {
 			warn("%s", argv[n]);
+			close(fd);
+			free(path);
 			continue;
 		}
 		asprintf(&options[OPT_TSIZE].o_request, "%ju", sb.st_size);
 
 		if (verbose)
 			printf("putting %s to %s:%s [%s]\n",
-			    argv[n], hostname, targ, mode);
-		xmitfile(peer, port, fd, targ, mode);
+			    argv[n], hostname, path, mode);
+		xmitfile(peer, port, fd, path, mode);
+		close(fd);
+
+		free(path);
 	}
 }