Coverage Report

Created: 2026-06-30 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/tests/oss-fuzz/async_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
22
fuzz_event_handler(coap_session_t *session, const coap_event_t event) {
9
22
  (void)session;
10
22
  (void)event;
11
22
  return 0;
12
22
}
13
14
static void
15
async_handler(coap_resource_t *resource, coap_session_t *session,
16
              const coap_pdu_t *request, const coap_string_t *query,
17
12
              coap_pdu_t *response) {
18
12
  (void)resource;
19
12
  (void)query;
20
21
12
  size_t len;
22
12
  const uint8_t *databuf;
23
12
  coap_bin_const_t token = coap_pdu_get_token(request);
24
12
  coap_async_t *async = coap_find_async(session, token);
25
26
12
  if (async) {
27
0
    response->code = COAP_RESPONSE_CODE(205);
28
0
    if (coap_get_data(request, &len, &databuf) && len > 0) {
29
0
      coap_add_data(response, len, databuf);
30
0
    }
31
0
    coap_free_async(session, async);
32
12
  } else {
33
12
    response->code = COAP_RESPONSE_CODE(400);
34
12
    if (coap_get_data(request, &len, &databuf) && len > 0) {
35
10
      async = coap_register_async(session, request,
36
10
                                  (coap_tick_t)len * COAP_TICKS_PER_SECOND / 100);
37
10
      if (async && len > 1) {
38
9
        uint8_t *app_data = malloc(len);
39
9
        if (app_data) {
40
9
          memcpy(app_data, databuf, len);
41
9
          coap_async_set_app_data2(async, app_data, free);
42
9
          response->code = COAP_RESPONSE_CODE(0);
43
9
        }
44
9
      }
45
10
    }
46
12
  }
47
12
}
48
49
int
50
37
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
51
37
  coap_context_t *ctx = NULL;
52
37
  coap_session_t *session = NULL;
53
37
  coap_resource_t *resource = NULL;
54
37
  coap_address_t addr;
55
37
  coap_pdu_t *pdu = NULL;
56
57
37
  if (size < 16)
58
6
    return 0;
59
60
31
  coap_startup();
61
31
  coap_set_log_level(COAP_LOG_EMERG);
62
31
  coap_debug_set_packet_loss("50%");
63
31
  coap_debug_set_packet_fail("100%");
64
65
31
  ctx = coap_new_context(NULL);
66
31
  if (!ctx)
67
0
    goto cleanup;
68
31
  coap_register_event_handler(ctx, fuzz_event_handler);
69
70
31
  resource = coap_resource_init(coap_make_str_const("async"), 0);
71
31
  if (resource) {
72
31
    coap_register_request_handler(resource, COAP_REQUEST_GET, async_handler);
73
31
    coap_register_request_handler(resource, COAP_REQUEST_POST, async_handler);
74
31
    coap_add_resource(ctx, resource);
75
31
  }
76
77
31
  coap_address_init(&addr);
78
31
  addr.addr.sin.sin_family = AF_INET;
79
31
  addr.addr.sin.sin_port = htons(5683);
80
31
  addr.addr.sin.sin_addr.s_addr = htonl(0x7F000001);
81
82
31
  session = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP);
83
31
  if (!session)
84
0
    goto cleanup;
85
31
  session->state = COAP_SESSION_STATE_ESTABLISHED;
86
87
  /* Direct async API testing */
88
31
  size_t token_len = (size > 8) ? 8 : size;
89
31
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
90
31
                      coap_new_message_id(session), 128);
91
31
  if (pdu) {
92
31
    coap_add_token(pdu, token_len, data);
93
31
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 5, (const uint8_t *)"async");
94
95
31
    coap_async_t *async = coap_register_async(session, pdu,
96
31
                                              COAP_TICKS_PER_SECOND);
97
31
    if (async) {
98
31
      coap_bin_const_t token = {.length = token_len, .s = data};
99
31
      coap_async_t *found = coap_find_async(session, token);
100
101
31
      if (found && size > token_len) {
102
31
        coap_async_set_delay(async, COAP_TICKS_PER_SECOND / 10);
103
31
        coap_async_trigger(async);
104
105
        /* Test app data operations */
106
31
        coap_async_get_app_data(async);
107
31
      }
108
109
31
      coap_free_async(session, async);
110
31
    }
111
31
    coap_delete_pdu(pdu);
112
113
    /* Test registration failure path */
114
31
    if (size > 32) {
115
17
      pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_POST,
116
17
                          coap_new_message_id(session), 64);
117
17
      if (pdu) {
118
17
        coap_add_token(pdu, 4, &data[16]);
119
17
        coap_async_t *async2 = coap_register_async(session, pdu, 0);
120
17
        if (async2) {
121
17
          coap_async_set_delay(async2, COAP_TICKS_PER_SECOND * 2);
122
17
          coap_free_async(session, async2);
123
17
        }
124
17
        coap_delete_pdu(pdu);
125
17
      }
126
17
    }
127
31
  }
128
129
  /* Dispatch with programmatic PDU and raw wire format */
130
31
  coap_fuzz_dispatch(ctx, session, data, size, (const uint8_t *)"async", 5);
131
132
31
cleanup:
133
31
  if (session)
134
31
    coap_session_release(session);
135
31
  if (ctx)
136
31
    coap_free_context(ctx);
137
31
  coap_cleanup();
138
31
  return 0;
139
31
}