mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-08 10:32:53 +03:00
Merge pull request #283 from mrdeep1/mem_leak_hello
Possible to crash coap-server with uncompleted (D)TLS handshakes
This commit is contained in:
3 files changed
+36
-2
No files matched your search
@@ -29,6 +29,8 @@ typedef struct coap_fixed_point_t {
|
||||
} coap_fixed_point_t;
|
||||
|
||||
#define COAP_DEFAULT_SESSION_TIMEOUT 300
|
||||
#define COAP_PARTIAL_SESSION_TIMEOUT_TICKS (30 * COAP_TICKS_PER_SECOND)
|
||||
#define COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS 100
|
||||
|
||||
#define COAP_PROTO_NOT_RELIABLE(p) ((p)==COAP_PROTO_UDP || (p)==COAP_PROTO_DTLS)
|
||||
#define COAP_PROTO_RELIABLE(p) ((p)==COAP_PROTO_TCP || (p)==COAP_PROTO_TLS)
|
||||
|
||||
@@ -212,6 +212,7 @@ typedef struct coap_context_t {
|
||||
|
||||
unsigned int session_timeout; /**< Number of seconds of inactivity after which an unused session will be closed. 0 means use default. */
|
||||
unsigned int max_idle_sessions; /**< Maximum number of simultaneous unused sessions per endpoint. 0 means no maximum. */
|
||||
unsigned int max_handshake_sessions; /**< Maximum number of simultaneous negotating sessions per endpoint. 0 means use default. */
|
||||
unsigned int ping_timeout; /**< Minimum inactivity time before sending a ping message. 0 means disabled. */
|
||||
unsigned int csm_timeout; /**< Timeout for waiting for a CSM from the remote side. 0 means disabled. */
|
||||
|
||||
|
||||
+33
-2
@@ -448,7 +448,9 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint,
|
||||
const coap_packet_t *packet, coap_tick_t now) {
|
||||
coap_session_t *session = NULL;
|
||||
unsigned int num_idle = 0;
|
||||
unsigned int num_hs = 0;
|
||||
coap_session_t *oldest = NULL;
|
||||
coap_session_t *oldest_hs = NULL;
|
||||
|
||||
endpoint->hello.ifindex = -1;
|
||||
|
||||
@@ -460,15 +462,44 @@ coap_endpoint_get_session(coap_endpoint_t *endpoint,
|
||||
session->last_rx_tx = now;
|
||||
return session;
|
||||
}
|
||||
if (session->ref == 0 && session->delayqueue == NULL && session->type == COAP_SESSION_TYPE_SERVER) {
|
||||
if (session->ref == 0 && session->delayqueue == NULL &&
|
||||
session->type == COAP_SESSION_TYPE_SERVER) {
|
||||
++num_idle;
|
||||
if (oldest==NULL || session->last_rx_tx < oldest->last_rx_tx)
|
||||
oldest = session;
|
||||
|
||||
if (session->state == COAP_SESSION_STATE_HANDSHAKE) {
|
||||
++num_hs;
|
||||
/* See if this is a partial SSL session set up
|
||||
which needs to be cleared down to prevent DOS */
|
||||
if ((session->last_rx_tx + COAP_PARTIAL_SESSION_TIMEOUT_TICKS) < now) {
|
||||
if (oldest_hs == NULL ||
|
||||
session->last_rx_tx < oldest_hs->last_rx_tx)
|
||||
oldest_hs = session;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (endpoint->context->max_idle_sessions > 0 && num_idle >= endpoint->context->max_idle_sessions)
|
||||
if (endpoint->context->max_idle_sessions > 0 &&
|
||||
num_idle >= endpoint->context->max_idle_sessions) {
|
||||
coap_session_free(oldest);
|
||||
}
|
||||
else if (oldest_hs) {
|
||||
coap_log(LOG_WARNING, "***%s: Incomplete session timed out\n",
|
||||
coap_session_str(oldest_hs));
|
||||
coap_session_free(oldest_hs);
|
||||
}
|
||||
|
||||
if (num_hs > (endpoint->context->max_handshake_sessions ?
|
||||
endpoint->context->max_handshake_sessions :
|
||||
COAP_DEFAULT_MAX_HANDSHAKE_SESSIONS)) {
|
||||
/* Maxed out on number of session in SSL negotiation state */
|
||||
coap_log(LOG_DEBUG,
|
||||
"Oustanding sessions in COAP_SESSION_STATE_HANDSHAKE too "
|
||||
"large. New request ignored\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (endpoint->proto == COAP_PROTO_DTLS) {
|
||||
session = &endpoint->hello;
|
||||
|
||||
Reference in new issue
Block a user