/src/libcoap/tests/oss-fuzz/block_target.c
Line | Count | Source |
1 | | #include "coap3/coap_internal.h" |
2 | | #include <stdint.h> |
3 | | #include <string.h> |
4 | | #include <stdlib.h> |
5 | | |
6 | | /* Resource handler - exercises coap_add_data_large_response() */ |
7 | | static void |
8 | | block_handler(coap_resource_t *resource, coap_session_t *session, |
9 | | const coap_pdu_t *request, const coap_string_t *query, |
10 | 0 | coap_pdu_t *response) { |
11 | 0 | (void)query; |
12 | 0 | size_t len; |
13 | 0 | const uint8_t *databuf; |
14 | |
|
15 | 0 | response->code = COAP_RESPONSE_CODE(205); |
16 | |
|
17 | 0 | if (coap_get_data(request, &len, &databuf) && len > 64) { |
18 | | /* Large payload - use block transfer API */ |
19 | 0 | coap_add_data_large_response(resource, session, request, response, |
20 | 0 | query, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0, |
21 | 0 | len, databuf, NULL, NULL); |
22 | 0 | } else if (len > 0) { |
23 | 0 | coap_add_data(response, len, databuf); |
24 | 0 | } else { |
25 | | /* Generate 256-byte response to trigger BLOCK2 */ |
26 | 0 | static const uint8_t large_data[256] = { |
27 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
28 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
29 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
30 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
31 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
32 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
33 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
34 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
35 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
36 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
37 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
38 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
39 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
40 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
41 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', |
42 | 0 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' |
43 | 0 | }; |
44 | 0 | coap_add_data_large_response(resource, session, request, response, |
45 | 0 | query, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0, |
46 | 0 | sizeof(large_data), large_data, NULL, |
47 | 0 | NULL); |
48 | 0 | } |
49 | 0 | } |
50 | | |
51 | | int |
52 | 81 | LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
53 | 81 | coap_context_t *ctx = NULL; |
54 | 81 | coap_session_t *session = NULL; |
55 | 81 | coap_resource_t *resource = NULL; |
56 | 81 | coap_address_t addr; |
57 | 81 | uint8_t *dgram = NULL; |
58 | | |
59 | 81 | if (size < 8) |
60 | 4 | return 0; |
61 | | |
62 | 77 | coap_startup(); |
63 | 77 | coap_set_log_level(COAP_LOG_EMERG); |
64 | 77 | coap_debug_set_packet_loss("50%"); |
65 | 77 | coap_debug_set_packet_fail("100%"); |
66 | | |
67 | 77 | ctx = coap_new_context(NULL); |
68 | 77 | if (!ctx) |
69 | 0 | goto cleanup; |
70 | | |
71 | | /* Configure block mode and max block size */ |
72 | 77 | uint32_t block_mode = ((uint32_t)data[0] << 8) | data[1]; |
73 | 77 | coap_context_set_block_mode(ctx, block_mode & 0x0F); |
74 | | |
75 | 77 | uint16_t max_block = ((uint16_t)data[2] << 8) | data[3]; |
76 | 77 | if (max_block >= 16 && max_block <= 1024) { |
77 | 39 | coap_context_set_max_block_size(ctx, max_block); |
78 | 39 | } |
79 | | |
80 | | /* Create resource */ |
81 | 77 | resource = coap_resource_init(coap_make_str_const("data"), 0); |
82 | 77 | if (resource) { |
83 | 77 | coap_register_request_handler(resource, COAP_REQUEST_GET, block_handler); |
84 | 77 | coap_register_request_handler(resource, COAP_REQUEST_PUT, block_handler); |
85 | 77 | coap_register_request_handler(resource, COAP_REQUEST_POST, block_handler); |
86 | 77 | coap_add_resource(ctx, resource); |
87 | 77 | } |
88 | | |
89 | | /* Create session */ |
90 | 77 | coap_address_init(&addr); |
91 | 77 | addr.addr.sa.sa_family = AF_INET; |
92 | 77 | session = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP); |
93 | 77 | if (!session) |
94 | 0 | goto cleanup; |
95 | 77 | session->state = COAP_SESSION_STATE_ESTABLISHED; |
96 | | |
97 | | /* Process datagram */ |
98 | 77 | size_t dgram_len = size - 4; |
99 | 77 | dgram = (uint8_t *)malloc(dgram_len); |
100 | 77 | if (dgram) { |
101 | 77 | memcpy(dgram, data + 4, dgram_len); |
102 | 77 | coap_handle_dgram(ctx, session, dgram, dgram_len); |
103 | 77 | free(dgram); |
104 | 77 | } |
105 | | |
106 | 77 | cleanup: |
107 | 77 | if (session) |
108 | 77 | coap_session_release(session); |
109 | 77 | if (ctx) |
110 | 77 | coap_free_context(ctx); |
111 | 77 | coap_cleanup(); |
112 | 77 | return 0; |
113 | 77 | } |