coap_net.c: Check for invalid PDU class codes

This commit is contained in:
Jon Shallow authored and Jon Shallow committed 2023-12-27 11:31:26 +00:00
1 parent e7105286f6
commit cc1cc1ad27
5 files changed
+90 -7

No files matched your search

+9 -3
View File
@@ -318,6 +318,7 @@ event_handler(coap_session_t *session COAP_UNUSED,
case COAP_EVENT_OSCORE_DECODE_ERROR:
case COAP_EVENT_WS_PACKET_SIZE:
case COAP_EVENT_WS_CLOSED:
case COAP_EVENT_BAD_PACKET:
quit = 1;
break;
case COAP_EVENT_DTLS_CONNECTED:
@@ -331,7 +332,6 @@ event_handler(coap_session_t *session COAP_UNUSED,
case COAP_EVENT_XMIT_BLOCK_FAIL:
case COAP_EVENT_SERVER_SESSION_NEW:
case COAP_EVENT_SERVER_SESSION_DEL:
case COAP_EVENT_BAD_PACKET:
case COAP_EVENT_MSG_RETRANSMITTED:
case COAP_EVENT_WS_CONNECTED:
case COAP_EVENT_KEEPALIVE_FAILURE:
@@ -357,7 +357,6 @@ nack_handler(coap_session_t *session COAP_UNUSED,
switch (reason) {
case COAP_NACK_TOO_MANY_RETRIES:
case COAP_NACK_NOT_DELIVERABLE:
case COAP_NACK_RST:
case COAP_NACK_TLS_FAILED:
case COAP_NACK_WS_FAILED:
case COAP_NACK_TLS_LAYER_FAILED:
@@ -365,8 +364,15 @@ nack_handler(coap_session_t *session COAP_UNUSED,
coap_log_err("cannot send CoAP pdu\n");
quit = 1;
break;
case COAP_NACK_ICMP_ISSUE:
case COAP_NACK_RST:
coap_log_info("received RST pdu response\n");
quit = 1;
break;
case COAP_NACK_BAD_RESPONSE:
coap_log_info("received bad response pdu\n");
quit = 1;
break;
case COAP_NACK_ICMP_ISSUE:
default:
;
}
+10
View File
@@ -393,6 +393,16 @@ coap_pdu_t *coap_wellknown_response(coap_context_t *context,
*/
unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r);
/**
* Check whether the pdu contains a valid code class
*
* @param session The CoAP session.
* @param pdu The PDU to check.
*
* @return @c 1 valid, @c 0 invalid.
*/
int coap_check_code_class(coap_session_t *session, coap_pdu_t *pdu);
/**
* Sends a CoAP message to given peer. The memory that is
* allocated for the pdu will be released by coap_send_internal().
+2 -1
View File
@@ -100,7 +100,8 @@
#define COAP_PDU_IS_EMPTY(pdu) ((pdu)->code == 0)
#define COAP_PDU_IS_REQUEST(pdu) (!COAP_PDU_IS_EMPTY(pdu) && (pdu)->code < 32)
#define COAP_PDU_IS_RESPONSE(pdu) ((pdu)->code >= 64 && (pdu)->code < 224)
/* Code 1.xx (32-63) and 6.xx (192-224) currently invalid */
#define COAP_PDU_IS_RESPONSE(pdu) ((pdu)->code >= 64 && (pdu)->code < 192)
#define COAP_PDU_IS_SIGNALING(pdu) ((pdu)->code >= 224)
#define COAP_PDU_IS_PING(pdu) ((COAP_PDU_IS_EMPTY(pdu) && \
((pdu)->type == COAP_MESSAGE_CON)) || \
+60 -3
View File
@@ -1076,6 +1076,34 @@ coap_client_delay_first(coap_session_t *session) {
return 1;
}
/*
* return 0 Invalid
* 1 Valid
*/
int
coap_check_code_class(coap_session_t *session, coap_pdu_t *pdu) {
/* Check validity of sending code */
switch (COAP_RESPONSE_CLASS(pdu->code)) {
case 0: /* Empty or request */
case 2: /* Success */
case 3: /* Reserved for future use */
case 4: /* Client error */
case 5: /* Server error */
break;
case 7: /* Reliable signalling */
if (COAP_PROTO_RELIABLE(session->proto))
break;
/* Not valid if UDP */
/* Fall through */
case 1: /* Invalid */
case 6: /* Invalid */
default:
return 0;
}
return 1;
}
coap_mid_t
coap_send(coap_session_t *session, coap_pdu_t *pdu) {
coap_mid_t mid = COAP_INVALID_MID;
@@ -1091,6 +1119,14 @@ coap_send(coap_session_t *session, coap_pdu_t *pdu) {
assert(pdu);
coap_lock_check_locked(session->context);
/* Check validity of sending code */
if (!coap_check_code_class(session, pdu)) {
coap_log_err("coap_send: Invalid PDU code (%d.%02d)\n",
COAP_RESPONSE_CLASS(pdu->code),
pdu->code & 0x1f);
goto error;
}
pdu->session = session;
#if COAP_CLIENT_SUPPORT
if (session->type == COAP_SESSION_TYPE_CLIENT &&
@@ -1416,11 +1452,9 @@ send_it:
#endif /* COAP_CLIENT_SUPPORT */
return mid;
#if COAP_CLIENT_SUPPORT
error:
coap_delete_pdu(pdu);
return COAP_INVALID_MID;
#endif
}
coap_mid_t
@@ -3222,6 +3256,14 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu
coap_lock_callback(context,
h(resource, session, pdu, query, response));
/* Check validity of response code */
if (!coap_check_code_class(session, response)) {
coap_log_warn("handle_request: Invalid PDU response code (%d.%02d)\n",
COAP_RESPONSE_CLASS(response->code),
response->code & 0x1f);
goto drop_it_no_debug;
}
/* Check if lg_xmit generated and update PDU code if so */
coap_check_code_lg_xmit(session, pdu, response, resource, query);
@@ -3603,6 +3645,20 @@ coap_dispatch(coap_context_t *context, coap_session_t *session,
pdu->session = session;
coap_show_pdu(COAP_LOG_DEBUG, pdu);
/* Check validity of received code */
if (!coap_check_code_class(session, pdu)) {
coap_log_info("coap_dispatch: Received invalid PDU code (%d.%02d)\n",
COAP_RESPONSE_CLASS(pdu->code),
pdu->code & 0x1f);
packet_is_bad = 1;
if (pdu->type == COAP_MESSAGE_CON) {
coap_send_message_type(session, pdu, COAP_MESSAGE_RST);
}
/* find message id in sendqueue to stop retransmission */
coap_remove_from_queue(&context->sendqueue, session, pdu->mid, &sent);
goto cleanup;
}
coap_option_filter_clear(&opt_filter);
#if COAP_OSCORE_SUPPORT
@@ -3917,7 +3973,8 @@ coap_dispatch(coap_context_t *context, coap_session_t *session,
}
}
} else {
coap_send_message_type(session, pdu, COAP_MESSAGE_RST);
if (pdu->type == COAP_MESSAGE_CON)
coap_send_message_type(session, pdu, COAP_MESSAGE_RST);
}
}
}
+9
View File
@@ -1108,6 +1108,15 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r,
coap_lock_callback(obs->session->context,
h(r, obs->session, obs->pdu, query, response));
/* Check validity of response code */
if (!coap_check_code_class(obs->session, response)) {
coap_log_warn("handle_request: Invalid PDU response code (%d.%02d)\n",
COAP_RESPONSE_CLASS(response->code),
response->code & 0x1f);
coap_delete_pdu(response);
return;
}
/* Check if lg_xmit generated and update PDU code if so */
coap_check_code_lg_xmit(obs->session, obs->pdu, response, r, query);
coap_delete_string(query);