[PATCH] sftp: check the argument to -R for validity

762233433 at qq.com 762233433 at qq.com
Tue Nov 3 18:26:50 AEDT 2026


From: xuehaolin <xuehaolin at uniontech.com>

The -R option is parsed with strtol() and the result assigned to a
size_t without any range checking beyond rejecting zero and trailing
garbage.  Negative values therefore wrap around when the value is
truncated to the u_int num_requests member of struct sftp_conn (e.g.
"-R -5" becomes 4294967291), and values above the limit applied to the
equivalent "-X nrequests=" option are silently truncated.

The practical impact of a negative value is that it defeats the
flow-control window: the client sends every request for the file
without waiting for replies, so the server has to absorb them all at
once.

Parse the argument with strtonum(), matching the "-X nrequests=" code
path, and report the reason for rejection.  Document the maximum in
sftp.1.
---
 sftp.1 |  1 +
 sftp.c | 14 ++++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/sftp.1 b/sftp.1
index a30338b..c220059 100644
--- a/sftp.1
+++ b/sftp.1
@@ -339,6 +339,7 @@ Specify how many requests may be outstanding at any one time.
 Increasing this may slightly improve file transfer speed
 but will increase memory usage.
 The default is 64 outstanding requests.
+The maximum supported value is 262144.
 .It Fl r
 Recursively copy entire directories when uploading and downloading.
 Note that
diff --git a/sftp.c b/sftp.c
index fdc5167..5350ca4 100644
--- a/sftp.c
+++ b/sftp.c
@@ -2642,10 +2642,16 @@ main(int argc, char **argv)
 			global_rflag = 1;
 			break;
 		case 'R':
-			num_requests = strtol(optarg, &cp, 10);
-			if (num_requests == 0 || *cp != '\0')
-				fatal("Invalid number of requests \"%s\"",
-				    optarg);
+			/*
+			 * Bound the value so that a negative argument cannot
+			 * wrap into an enormous size_t; -X nrequests= uses
+			 * the same range.
+			 */
+			llv = strtonum(optarg, 1, 256 * 1024, &errstr);
+			if (errstr != NULL)
+				fatal("Invalid number of requests \"%s\": %s",
+				    optarg, errstr);
+			num_requests = (size_t)llv;
 			break;
 		case 's':
 			sftp_server = optarg;



More information about the openssh-unix-dev mailing list