Coverage Report

Created: 2026-08-14 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/tests/oss-fuzz/block_check_target.c
Line
Count
Source
1
#include "coap3/coap_internal.h"
2
#include <stdint.h>
3
#include <string.h>
4
5
static int
6
19
fuzz_event_handler(coap_session_t *session, const coap_event_t event) {
7
19
  (void)session;
8
19
  (void)event;
9
19
  return 0;
10
19
}
11
12
static uint8_t test_data[4096];
13
14
int
15
33
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
16
33
  if (size < 20) {
17
8
    return 0;
18
8
  }
19
20
102k
  for (size_t i = 0; i < sizeof(test_data); i++) {
21
102k
    test_data[i] = (uint8_t)(i & 0xFF);
22
102k
  }
23
24
25
  coap_startup();
25
25
  coap_set_log_level(COAP_LOG_EMERG);
26
25
  coap_dtls_set_log_level(COAP_LOG_EMERG);
27
25
  coap_debug_set_packet_loss("50%");
28
25
  coap_debug_set_packet_fail("100%");
29
30
25
  coap_context_t *ctx = coap_new_context(NULL);
31
25
  if (!ctx) {
32
0
    return 0;
33
0
  }
34
25
  coap_register_event_handler(ctx, fuzz_event_handler);
35
36
25
  if (data[0] & 0x01) {
37
14
    ctx->block_mode |= COAP_BLOCK_USE_LIBCOAP;
38
14
  }
39
25
  if (data[0] & 0x04) {
40
10
    ctx->block_mode |= (COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_HAS_Q_BLOCK);
41
10
  }
42
43
25
  coap_address_t addr;
44
25
  coap_address_init(&addr);
45
25
  addr.addr.sa.sa_family = AF_INET;
46
47
25
  coap_endpoint_t *ep = coap_new_endpoint(ctx, &addr, COAP_PROTO_UDP);
48
25
  if (!ep) {
49
0
    coap_free_context(ctx);
50
0
    return 0;
51
0
  }
52
53
25
  coap_session_t *session = coap_new_client_session(ctx, NULL, &addr,
54
25
                                                    COAP_PROTO_UDP);
55
25
  if (!session) {
56
0
    coap_free_context(ctx);
57
0
    return 0;
58
0
  }
59
60
25
  coap_str_const_t *uri = coap_make_str_const("test");
61
25
  coap_resource_t *resource = coap_resource_init(uri, 0);
62
25
  if (resource) {
63
25
    coap_add_resource(ctx, resource);
64
25
  }
65
66
25
  unsigned int block_szx = (size > 1) ? (data[1] % 7) : 2;
67
25
  size_t data_len = ((data[2] % 32) + 1) * 64;
68
25
  if (data_len > sizeof(test_data)) {
69
0
    data_len = sizeof(test_data);
70
0
  }
71
25
  uint32_t block_num = (size > 4) ? (data[4] % 16) : 0;
72
73
  /* Populate lg_xmit so timeout functions iterate a non-empty list */
74
25
  {
75
25
    uint32_t saved_mode = session->block_mode;
76
25
    session->block_mode |= COAP_BLOCK_USE_LIBCOAP;
77
25
    coap_pdu_t *setup_pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
78
25
                                          coap_new_message_id(session),
79
25
                                          coap_session_max_pdu_size(session));
80
25
    if (setup_pdu) {
81
25
      coap_add_option(setup_pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
82
25
      coap_add_data_large_request_lkd(session, setup_pdu, sizeof(test_data),
83
25
                                      test_data, NULL, NULL);
84
25
      coap_delete_pdu(setup_pdu);
85
25
    }
86
25
    session->block_mode = saved_mode;
87
25
  }
88
89
25
  coap_tick_t now, tim_rem;
90
25
  coap_ticks(&now);
91
92
  /* Timeout handlers */
93
25
  coap_block_check_lg_xmit_timeouts(session, now, &tim_rem);
94
25
  coap_block_check_lg_crcv_timeouts(session, now, &tim_rem);
95
25
  coap_block_check_lg_srcv_timeouts(session, now, &tim_rem);
96
25
  coap_block_check_q_block1_xmit(session, now, &tim_rem);
97
25
  coap_block_check_q_block2_xmit(session, now, &tim_rem);
98
99
  /* Low-level block encoding */
100
25
  coap_pdu_t *pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
101
25
                                  coap_new_message_id(session),
102
25
                                  coap_session_max_pdu_size(session));
103
25
  if (pdu) {
104
25
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
105
106
25
    if (coap_add_block(pdu, data_len, test_data, block_num, block_szx)) {
107
17
      coap_block_t block;
108
17
      memset(&block, 0, sizeof(block));
109
17
      block.num = block_num;
110
17
      block.szx = block_szx;
111
17
      block.m = (size > 5) ? (data[5] & 0x01) : 0;
112
17
      coap_write_block_opt(&block, COAP_OPTION_BLOCK1, pdu, data_len);
113
17
    }
114
115
25
    coap_block_t block_read;
116
25
    if (coap_get_block(pdu, COAP_OPTION_BLOCK1, &block_read)) {
117
17
      (void)block_read.num;
118
17
    }
119
25
    coap_delete_pdu(pdu);
120
25
  }
121
122
  /* BERT block encoding */
123
25
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
124
25
                      coap_new_message_id(session),
125
25
                      coap_session_max_pdu_size(session));
126
25
  if (pdu) {
127
25
    coap_block_b_t block_b;
128
25
    memset(&block_b, 0, sizeof(block_b));
129
25
    block_b.num = (size > 6) ? (data[6] % 32) : 0;
130
25
    block_b.szx = block_szx;
131
25
    block_b.m = (size > 7) ? (data[7] & 0x01) : 0;
132
25
    block_b.aszx = block_szx;
133
25
    coap_write_block_b_opt(session, &block_b, COAP_OPTION_BLOCK1, pdu,
134
25
                           data_len);
135
136
25
    coap_pdu_t *resp = coap_pdu_init(COAP_MESSAGE_ACK, COAP_RESPONSE_CODE(205),
137
25
                                     coap_new_message_id(session), 1152);
138
25
    if (resp) {
139
25
      coap_add_block_b_data(resp, data_len, test_data, &block_b);
140
25
      coap_delete_pdu(resp);
141
25
    }
142
25
    coap_delete_pdu(pdu);
143
25
  }
144
145
  /* Large data transfer APIs */
146
25
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
147
25
                      coap_new_message_id(session),
148
25
                      coap_session_max_pdu_size(session));
149
25
  if (pdu && resource) {
150
25
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
151
152
25
    coap_pdu_t *resp = coap_pdu_init(COAP_MESSAGE_ACK, COAP_RESPONSE_CODE(205),
153
25
                                     coap_new_message_id(session),
154
25
                                     coap_session_max_pdu_size(session));
155
25
    if (resp) {
156
25
      coap_add_data_large_response(resource, session, pdu, resp,
157
25
                                   NULL, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0,
158
25
                                   data_len, test_data, NULL, NULL);
159
160
25
      coap_pdu_t *resp2 = coap_pdu_init(COAP_MESSAGE_ACK,
161
25
                                        COAP_RESPONSE_CODE(205),
162
25
                                        coap_new_message_id(session), 1152);
163
25
      if (resp2) {
164
25
        coap_add_data_blocked_response(pdu, resp2, COAP_MEDIATYPE_TEXT_PLAIN,
165
25
                                       -1, data_len, test_data);
166
25
        coap_delete_pdu(resp2);
167
25
      }
168
25
      coap_delete_pdu(resp);
169
25
    }
170
25
    coap_delete_pdu(pdu);
171
25
  }
172
173
  /* Large request with lock */
174
25
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
175
25
                      coap_new_message_id(session),
176
25
                      coap_session_max_pdu_size(session));
177
25
  if (pdu) {
178
25
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
179
25
    coap_lock_lock(return 0);
180
25
    coap_add_data_large_request_lkd(session, pdu, data_len, test_data, NULL,
181
25
                                    NULL);
182
25
    coap_lock_unlock();
183
25
    coap_delete_pdu(pdu);
184
25
  }
185
186
  /* Q-Block support check */
187
25
  (void)coap_q_block_is_supported();
188
189
  /* Observe cancellation */
190
25
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
191
25
                      coap_new_message_id(session),
192
25
                      coap_session_max_pdu_size(session));
193
25
  if (pdu) {
194
25
    coap_add_option(pdu, COAP_OPTION_OBSERVE, 0, NULL);
195
196
25
    uint8_t token_buf[8];
197
25
    coap_binary_t token;
198
25
    token.length = (size > 8) ? ((data[8] % 8) + 1) : 1;
199
25
    if (token.length > sizeof(token_buf)) {
200
0
      token.length = sizeof(token_buf);
201
0
    }
202
25
    memcpy(token_buf, (size > 16) ? (data + 12) : data, token.length);
203
25
    token.s = token_buf;
204
205
25
    coap_cancel_observe(session, &token, COAP_MESSAGE_CON);
206
25
    coap_lock_lock(return 0);
207
25
    coap_cancel_observe_lkd(session, &token, COAP_MESSAGE_CON);
208
25
    coap_lock_unlock();
209
25
    coap_delete_pdu(pdu);
210
25
  }
211
212
  /* Lifecycle cleanup */
213
25
  coap_block_delete_lg_crcv(session, NULL);
214
25
  coap_block_delete_lg_xmit(session, NULL);
215
25
  coap_register_block_data_handler(ctx, NULL);
216
217
25
  coap_io_process(ctx, 1);
218
25
  coap_free_context(ctx);
219
25
  coap_cleanup();
220
221
25
  return 0;
222
25
}