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