[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