[openssh-commits] [openssh] 05/08: upstream: avoid situation where sftp_download() could get stuck in

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Jun 29 12:21:32 AEST 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit c1cebbc7c69acfe5df07b4a95e4c32cebc3e105a
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Mon Jun 29 01:53:21 2026 +0000

    upstream: avoid situation where sftp_download() could get stuck in
    
    a loop if a broken server repeatedly returned zero length while reading a
    file. Identified by Swival scanner
    
    OpenBSD-Commit-ID: 53f1de5065ff01952d2abb51747c2418ce21cd96
---
 sftp-client.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/sftp-client.c b/sftp-client.c
index 69ef28cdc..1f031128e 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.185 2026/03/03 09:57:25 dtucker Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.186 2026/06/29 01:53:21 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm at openbsd.org>
  *
@@ -1585,7 +1585,7 @@ sftp_download(struct sftp_conn *conn, const char *remote_path,
 {
 	struct sshbuf *msg;
 	u_char *handle;
-	int local_fd = -1, write_error;
+	int local_fd = -1, write_error, seen_zerolen = 0;
 	int read_error, write_errno, lmodified = 0, reordered = 0, r;
 	uint64_t offset = 0, size, highwater = 0, maxack = 0;
 	u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK;
@@ -1733,6 +1733,11 @@ sftp_download(struct sftp_conn *conn, const char *remote_path,
 			if (len > req->len)
 				fatal("Received more data than asked for "
 				    "%zu > %zu", len, req->len);
+			if (len == 0) {
+				if (seen_zerolen)
+					fatal_f("server sent zero data length");
+				seen_zerolen = 1;
+			}
 			lmodified = 1;
 			if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
 			    atomicio(vwrite, local_fd, data, len) != len) &&
@@ -2446,7 +2451,7 @@ sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
     Attrib *a, int preserve_flag)
 {
 	struct sshbuf *msg;
-	int write_error, read_error, r;
+	int write_error, read_error, r, seen_zerolen = 0;
 	uint64_t offset = 0, size;
 	u_int id, buflen, num_req, max_req, status = SSH2_FX_OK;
 	u_int num_upload_req;
@@ -2576,6 +2581,11 @@ sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
 			if (len > req->len)
 				fatal("Received more data than asked for "
 				    "%zu > %zu", len, req->len);
+			if (len == 0) {
+				if (seen_zerolen)
+					fatal_f("server sent zero data length");
+				seen_zerolen = 1;
+			}
 
 			/* Write this chunk out to the destination */
 			sshbuf_reset(msg);

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list