Merge pull request #283 from mrdeep1/mem_leak_hello

Possible to crash coap-server with uncompleted (D)TLS handshakes
This commit is contained in:
obgm authored and GitHub committed 2018-12-18 17:45:04 +01:00
commit 49e8e43eeb
3 files changed
+36 -2

No files matched your search

+2
View File
@@ -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)
+1
View File
@@ -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
View File
@@ -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;