curl_multi_fdset: make FD_SET() not operate on sockets out of range

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
This commit is contained in:
Daniel Stenberg 2021-09-14 13:03:06 +02:00
Родитель 7aa79dce10
Коммит d5a70e77b2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
2 изменённых файлов: 21 добавлений и 13 удалений

Просмотреть файл

@ -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];
}

Просмотреть файл

@ -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 */