]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
telnet: honor CURLOPT_TIMEOUT in send_telnet_data()
authorJoshua Rogers <MegaManSec@users.noreply.github.com>
Tue, 19 May 2026 22:37:27 +0000 (00:37 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 2 Jun 2026 09:43:00 +0000 (11:43 +0200)
The poll-before-write loop used -1 (infinite) as the Curl_poll timeout,
so a peer that stops reading could stall the transfer indefinitely,
bypassing CURLOPT_TIMEOUT. Use Curl_timeleft_ms() instead and return
CURLE_OPERATION_TIMEDOUT when the deadline is reached or exceeded.

Closes #21685

lib/telnet.c

index d1faec87a87d086a08c38a2ff8c9086816658ee5..83114ef2aa647828bcaf0397f9df7d995a5be732 100644 (file)
@@ -53,6 +53,7 @@
 #include "curl_trc.h"
 #include "progress.h"
 #include "arpa_telnet.h"
+#include "connect.h"
 #include "select.h"
 #include "curlx/strparse.h"
 
@@ -645,13 +646,19 @@ static CURLcode send_telnet_data(struct Curl_easy *data,
   while(!result && total_written < outlen) {
     /* Make sure socket is writable to avoid EWOULDBLOCK condition */
     struct pollfd pfd[1];
+    timediff_t timeout_ms = Curl_timeleft_ms(data);
     pfd[0].fd = conn->sock[FIRSTSOCKET];
     pfd[0].events = POLLOUT;
-    switch(Curl_poll(pfd, 1, -1)) {
+    if(timeout_ms < 0)
+      return CURLE_OPERATION_TIMEDOUT;
+    /* 0 means no timeout configured; pass -1 to poll for infinite wait */
+    switch(Curl_poll(pfd, 1, timeout_ms ? timeout_ms : -1)) {
     case -1:                    /* error, abort writing */
-    case 0:                     /* timeout (will never happen) */
       result = CURLE_SEND_ERROR;
       break;
+    case 0:                     /* timeout */
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
     default:                    /* write! */
       bytes_written = 0;
       result = Curl_xfer_send(data, outbuf + total_written,