mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-08-09 09:51:49 +08:00
cstp_send: fix worker hang and buffer overread on TLS send
A worker could get permanently stuck when a client disappeared silently (e.g. iOS roaming between WiFi and cellular): the TLS send loop retried indefinitely on GNUTLS_E_AGAIN with no deadline, requiring SIGKILL to recover. A separate bug caused a buffer overread on partial sends: the retry used the original data_size instead of the remaining byte count, so the send pointer advanced past the end of the caller's buffer. Resolves: #638 Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
+9
-9
@@ -31,6 +31,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
@@ -102,18 +103,17 @@ ssize_t cstp_send(worker_st *ws, const void *data, size_t data_size)
|
||||
|
||||
if (ws->session != NULL) {
|
||||
while (left > 0) {
|
||||
ret = gnutls_record_send(ws->session, p, data_size);
|
||||
ret = gnutls_record_send(ws->session, p, left);
|
||||
if (ret < 0) {
|
||||
struct pollfd pfd = { ws->conn_fd, POLLOUT, 0 };
|
||||
if (ret != GNUTLS_E_AGAIN &&
|
||||
ret != GNUTLS_E_INTERRUPTED) {
|
||||
ret != GNUTLS_E_INTERRUPTED)
|
||||
return ret;
|
||||
} else {
|
||||
/* do not cause mayhem */
|
||||
ms_sleep(20);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
/* wait for writability; peer gone if timeout */
|
||||
if (poll(&pfd, 1,
|
||||
DEFAULT_SOCKET_TIMEOUT * 1000) <= 0)
|
||||
return GNUTLS_E_PUSH_ERROR;
|
||||
} else if (ret > 0) {
|
||||
left -= ret;
|
||||
p += ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user