OSS-Fuzz: Add fuzzer for block low level checking

Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
This commit is contained in:
Arthur Chan authored and Jon Shallow committed 2026-03-28 10:44:50 +00:00
1 parent f283c7b69b
commit caa7120cae
4 files changed
+194

No files matched your search

+194
View File
@@ -0,0 +1,194 @@
#include "coap3/coap_internal.h"
#include <stdint.h>
#include <string.h>
static uint8_t test_data[4096];
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 20) {
return 0;
}
for (size_t i = 0; i < sizeof(test_data); i++) {
test_data[i] = (uint8_t)(i & 0xFF);
}
coap_startup();
coap_set_log_level(COAP_LOG_EMERG);
coap_dtls_set_log_level(COAP_LOG_EMERG);
coap_debug_set_packet_loss("50%");
coap_debug_set_packet_fail("100%");
coap_context_t *ctx = coap_new_context(NULL);
if (!ctx) {
return 0;
}
if (data[0] & 0x01) {
ctx->block_mode |= COAP_BLOCK_USE_LIBCOAP;
}
if (data[0] & 0x04) {
ctx->block_mode |= (COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_HAS_Q_BLOCK);
}
coap_address_t addr;
coap_address_init(&addr);
addr.addr.sa.sa_family = AF_INET;
coap_endpoint_t *ep = coap_new_endpoint(ctx, &addr, COAP_PROTO_UDP);
if (!ep) {
coap_free_context(ctx);
return 0;
}
coap_session_t *session = coap_new_client_session(ctx, NULL, &addr,
COAP_PROTO_UDP);
if (!session) {
coap_free_context(ctx);
return 0;
}
coap_str_const_t *uri = coap_make_str_const("test");
coap_resource_t *resource = coap_resource_init(uri, 0);
if (resource) {
coap_add_resource(ctx, resource);
}
unsigned int block_szx = (size > 1) ? (data[1] % 7) : 2;
size_t data_len = ((data[2] % 32) + 1) * 64;
if (data_len > sizeof(test_data)) {
data_len = sizeof(test_data);
}
uint32_t block_num = (size > 4) ? (data[4] % 16) : 0;
coap_tick_t now, tim_rem;
coap_ticks(&now);
/* Timeout handlers */
coap_block_check_lg_xmit_timeouts(session, now, &tim_rem);
coap_block_check_lg_crcv_timeouts(session, now, &tim_rem);
coap_block_check_lg_srcv_timeouts(session, now, &tim_rem);
coap_block_check_q_block1_xmit(session, now, &tim_rem);
coap_block_check_q_block2_xmit(session, now, &tim_rem);
/* Low-level block encoding */
coap_pdu_t *pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (pdu) {
coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
if (coap_add_block(pdu, data_len, test_data, block_num, block_szx)) {
coap_block_t block;
memset(&block, 0, sizeof(block));
block.num = block_num;
block.szx = block_szx;
block.m = (size > 5) ? (data[5] & 0x01) : 0;
coap_write_block_opt(&block, COAP_OPTION_BLOCK1, pdu, data_len);
}
coap_block_t block_read;
if (coap_get_block(pdu, COAP_OPTION_BLOCK1, &block_read)) {
(void)block_read.num;
}
coap_delete_pdu(pdu);
}
/* BERT block encoding */
pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (pdu) {
coap_block_b_t block_b;
memset(&block_b, 0, sizeof(block_b));
block_b.num = (size > 6) ? (data[6] % 32) : 0;
block_b.szx = block_szx;
block_b.m = (size > 7) ? (data[7] & 0x01) : 0;
block_b.aszx = block_szx;
coap_write_block_b_opt(session, &block_b, COAP_OPTION_BLOCK1, pdu,
data_len);
coap_pdu_t *resp = coap_pdu_init(COAP_MESSAGE_ACK, COAP_RESPONSE_CODE(205),
coap_new_message_id(session), 1152);
if (resp) {
coap_add_block_b_data(resp, data_len, test_data, &block_b);
coap_delete_pdu(resp);
}
coap_delete_pdu(pdu);
}
/* Large data transfer APIs */
pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (pdu && resource) {
coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
coap_pdu_t *resp = coap_pdu_init(COAP_MESSAGE_ACK, COAP_RESPONSE_CODE(205),
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (resp) {
coap_add_data_large_response(resource, session, pdu, resp,
NULL, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0,
data_len, test_data, NULL, NULL);
coap_pdu_t *resp2 = coap_pdu_init(COAP_MESSAGE_ACK,
COAP_RESPONSE_CODE(205),
coap_new_message_id(session), 1152);
if (resp2) {
coap_add_data_blocked_response(pdu, resp2, COAP_MEDIATYPE_TEXT_PLAIN,
-1, data_len, test_data);
coap_delete_pdu(resp2);
}
coap_delete_pdu(resp);
}
coap_delete_pdu(pdu);
}
/* Large request with lock */
pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (pdu) {
coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
coap_add_data_large_request_lkd(session, pdu, data_len, test_data, NULL,
NULL);
coap_delete_pdu(pdu);
}
/* Q-Block support check */
(void)coap_q_block_is_supported();
/* Observe cancellation */
pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (pdu) {
coap_add_option(pdu, COAP_OPTION_OBSERVE, 0, NULL);
uint8_t token_buf[8];
coap_binary_t token;
token.length = (size > 8) ? ((data[8] % 8) + 1) : 1;
if (token.length > sizeof(token_buf)) {
token.length = sizeof(token_buf);
}
memcpy(token_buf, (size > 16) ? (data + 12) : data, token.length);
token.s = token_buf;
coap_cancel_observe(session, &token, COAP_MESSAGE_CON);
coap_cancel_observe_lkd(session, &token, COAP_MESSAGE_CON);
coap_delete_pdu(pdu);
}
/* Lifecycle cleanup */
coap_block_delete_lg_crcv(session, NULL);
coap_block_delete_lg_xmit(session, NULL);
coap_register_block_data_handler(ctx, NULL);
coap_io_process(ctx, 1);
coap_free_context(ctx);
coap_cleanup();
return 0;
}