Skip to content

Commit

Permalink
coap_net.c: Check for invalid PDU class codes
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdeep1 committed Dec 27, 2023
1 parent e710528 commit cc1cc1a
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 7 deletions.
12 changes: 9 additions & 3 deletions examples/coap-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -357,16 +357,22 @@ 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:
case COAP_NACK_WS_LAYER_FAILED:
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:
;
}
Expand Down
10 changes: 10 additions & 0 deletions include/coap3/coap_net_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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().
Expand Down
3 changes: 2 additions & 1 deletion include/coap3/coap_pdu_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)) || \
Expand Down
63 changes: 60 additions & 3 deletions src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 &&
Expand Down Expand Up @@ -1416,11 +1452,9 @@ coap_send(coap_session_t *session, coap_pdu_t *pdu) {
#endif /* COAP_CLIENT_SUPPORT */
return mid;

#if COAP_CLIENT_SUPPORT
error:
coap_delete_pdu(pdu);
return COAP_INVALID_MID;
#endif
}

coap_mid_t
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/coap_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit cc1cc1a

Please sign in to comment.