Coverage Report

Created: 2026-10-17 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/tests/oss-fuzz/block_target.c
Line
Count
Source
1
#include "coap3/coap_internal.h"
2
#include "coap_fuzz_helper.h"
3
#include <stdint.h>
4
#include <string.h>
5
#include <stdlib.h>
6
7
static int
8
30
fuzz_event_handler(coap_session_t *session, const coap_event_t event) {
9
30
  (void)session;
10
30
  (void)event;
11
30
  return 0;
12
30
}
13
14
/* Resource handler - exercises coap_add_data_large_response() */
15
static void
16
block_handler(coap_resource_t *resource, coap_session_t *session,
17
              const coap_pdu_t *request, const coap_string_t *query,
18
40
              coap_pdu_t *response) {
19
40
  (void)query;
20
40
  size_t len;
21
40
  const uint8_t *databuf;
22
23
40
  response->code = COAP_RESPONSE_CODE(205);
24
25
40
  if (coap_get_data(request, &len, &databuf) && len > 64) {
26
    /* Large payload - use block transfer API */
27
4
    coap_add_data_large_response(resource, session, request, response,
28
4
                                 query, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0,
29
4
                                 len, databuf, NULL, NULL);
30
36
  } else if (len > 0) {
31
10
    coap_add_data(response, len, databuf);
32
26
  } else {
33
    /* Generate 256-byte response to trigger BLOCK2 */
34
26
    static const uint8_t large_data[256] = {
35
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
36
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
37
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
38
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
39
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
40
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
41
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
42
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
43
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
44
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
45
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
46
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
47
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
48
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
49
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
50
26
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
51
26
    };
52
26
    coap_add_data_large_response(resource, session, request, response,
53
26
                                 query, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0,
54
26
                                 sizeof(large_data), large_data, NULL,
55
26
                                 NULL);
56
26
  }
57
40
}
58
59
int
60
84
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
61
84
  coap_context_t *ctx = NULL;
62
84
  coap_session_t *session = NULL;
63
84
  coap_resource_t *resource = NULL;
64
84
  coap_address_t addr;
65
66
84
  if (size < 8)
67
4
    return 0;
68
69
80
  coap_startup();
70
80
  coap_set_log_level(COAP_LOG_EMERG);
71
80
  coap_debug_set_packet_loss("50%");
72
80
  coap_debug_set_packet_fail("100%");
73
74
80
  ctx = coap_new_context(NULL);
75
80
  if (!ctx)
76
0
    goto cleanup;
77
80
  coap_register_event_handler(ctx, fuzz_event_handler);
78
79
  /* Configure block mode and max block size */
80
80
  uint32_t block_mode = ((uint32_t)data[0] << 8) | data[1];
81
80
  coap_context_set_block_mode(ctx, block_mode & 0x0F);
82
83
80
  uint16_t max_block = ((uint16_t)data[2] << 8) | data[3];
84
80
  if (max_block >= 16 && max_block <= 1024) {
85
43
    coap_context_set_max_block_size(ctx, max_block);
86
43
  }
87
88
  /* Create resource with type and interface attributes */
89
80
  resource = coap_resource_init(coap_make_str_const("data"), 0);
90
80
  if (resource) {
91
80
    coap_register_request_handler(resource, COAP_REQUEST_GET, block_handler);
92
80
    coap_register_request_handler(resource, COAP_REQUEST_PUT, block_handler);
93
80
    coap_register_request_handler(resource, COAP_REQUEST_POST, block_handler);
94
80
    coap_add_attr(resource, coap_make_str_const("rt"),
95
80
                  coap_make_str_const("\"test\""), 0);
96
80
    coap_add_attr(resource, coap_make_str_const("if"),
97
80
                  coap_make_str_const("\"block\""), 0);
98
80
    coap_add_resource(ctx, resource);
99
80
  }
100
101
  /* Create session */
102
80
  coap_address_init(&addr);
103
80
  addr.addr.sa.sa_family = AF_INET;
104
80
  session = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP);
105
80
  if (!session)
106
0
    goto cleanup;
107
80
  session->state = COAP_SESSION_STATE_ESTABLISHED;
108
109
  /* Dispatch with programmatic PDU and raw wire format */
110
80
  coap_fuzz_dispatch(ctx, session, data, size, (const uint8_t *)"data", 4);
111
112
  /* Probe .well-known/core with a fuzz-derived query filter */
113
80
  {
114
80
    coap_pdu_t *wk = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
115
80
                                   coap_new_message_id(session),
116
80
                                   coap_session_max_pdu_size(session));
117
80
    if (wk) {
118
80
      coap_add_option(wk, COAP_OPTION_URI_PATH, 11,
119
80
                      (const uint8_t *)".well-known");
120
80
      coap_add_option(wk, COAP_OPTION_URI_PATH, 4,
121
80
                      (const uint8_t *)"core");
122
80
      uint8_t qlen = (data[4] % 16) + 1;
123
80
      if ((size_t)5 + qlen <= size)
124
42
        coap_add_option(wk, COAP_OPTION_URI_QUERY, qlen, data + 5);
125
80
      coap_lock_lock(goto cleanup);
126
80
      coap_dispatch(ctx, session, wk);
127
80
      coap_lock_unlock();
128
80
      coap_delete_pdu(wk);
129
80
    }
130
80
  }
131
132
80
cleanup:
133
80
  if (session)
134
80
    coap_session_release(session);
135
80
  if (ctx)
136
80
    coap_free_context(ctx);
137
80
  coap_cleanup();
138
80
  return 0;
139
80
}