]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl_multi_fdset: make FD_SET() not operate on sockets out of range
authorDaniel Stenberg <daniel@haxx.se>
Tue, 14 Sep 2021 11:03:06 +0000 (13:03 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 15 Sep 2021 12:34:00 +0000 (14:34 +0200)
The VALID_SOCK() macro was made to only check for FD_SETSIZE if curl was
built to use select(), even though the curl_multi_fdset() function
always and unconditionally uses FD_SET and needs the check.

Reported-by: 0xee on github
Fixes #7718
Closes #7719

lib/multi.c
lib/select.h

index 85097816db5937e8a1dc484cd32be0462354fb1b..518ceb51f57e952eac733d8886042004b83aeb3f 100644 (file)
@@ -1052,11 +1052,17 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
       curl_socket_t s = CURL_SOCKET_BAD;
 
-      if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+      if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK(sockbunch[i])) {
+        if(!FDSET_SOCK(sockbunch[i]))
+          /* pretend it doesn't exist */
+          continue;
         FD_SET(sockbunch[i], read_fd_set);
         s = sockbunch[i];
       }
-      if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+      if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK(sockbunch[i])) {
+        if(!FDSET_SOCK(sockbunch[i]))
+          /* pretend it doesn't exist */
+          continue;
         FD_SET(sockbunch[i], write_fd_set);
         s = sockbunch[i];
       }
index 19da1e774be93867de591397aa0ff922968bfc61..59a571dbbd9fd36f23f3a4b1d44dfacef02b3d54 100644 (file)
@@ -97,8 +97,10 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
 #if defined(TPF)
 #define VALID_SOCK(x) 1
 #define VERIFY_SOCK(x) Curl_nop_stmt
+#define FDSET_SOCK(x) 1
 #elif defined(USE_WINSOCK)
 #define VALID_SOCK(s) ((s) < INVALID_SOCKET)
+#define FDSET_SOCK(x) 1
 #define VERIFY_SOCK(x) do { \
   if(!VALID_SOCK(x)) { \
     SET_SOCKERRNO(WSAEINVAL); \
@@ -106,17 +108,17 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
   } \
 } while(0)
 #else
-#ifdef HAVE_POLL_FINE
-#define VALID_SOCK(s) ((s) >= 0)  /* FD_SETSIZE is irrelevant for poll */
-#else
-#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
-#endif
-#define VERIFY_SOCK(x) do { \
-  if(!VALID_SOCK(x)) { \
-    SET_SOCKERRNO(EINVAL); \
-    return -1; \
-  } \
-} while(0)
+#define VALID_SOCK(s) ((s) >= 0)
+
+/* If the socket is small enough to get set or read from an fdset */
+#define FDSET_SOCK(s) ((s) < FD_SETSIZE)
+
+#define VERIFY_SOCK(x) do {                     \
+    if(!VALID_SOCK(x) || !FDSET_SOCK(x)) {      \
+      SET_SOCKERRNO(EINVAL);                    \
+      return -1;                                \
+    }                                           \
+  } while(0)
 #endif
 
 #endif /* HEADER_CURL_SELECT_H */