1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <tftp/tftp.h>
6 #include <fbl/unique_ptr.h>
7 
8 #include "internal.h"
9 
10 #include <stdio.h>
11 #include <string.h>
12 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)13 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
14     uint8_t sess_buf[sizeof(tftp_session)];
15     tftp_session* session = nullptr;
16     if (tftp_init(&session, sess_buf, sizeof(tftp_session)) != TFTP_NO_ERROR) {
17         printf("tftp_init failed\n");
18         return 0;
19     }
20 
21     auto open_read_fn = [](const char* filename, void* cookie) -> ssize_t {
22         return 0;
23     };
24     auto open_write_fn = [](const char* filename, size_t size, void* cookie) -> tftp_status {
25         return TFTP_NO_ERROR;
26     };
27     auto read_fn = [](void* data, size_t* len, off_t offset, void* cookie) -> tftp_status {
28         return TFTP_NO_ERROR;
29     };
30     auto write_fn = [](const void* data, size_t* len, off_t offset, void* cookie) -> tftp_status {
31         return TFTP_NO_ERROR;
32     };
33     auto close_fn = [](void* cookie) {
34         return;
35     };
36     tftp_file_interface ifc = { open_read_fn, open_write_fn, read_fn, write_fn, close_fn };
37     if (tftp_session_set_file_interface(session, &ifc) != TFTP_NO_ERROR) {
38         return 0;
39     }
40 
41     uint16_t* block_size_ptr = nullptr;
42     uint16_t block_size;
43     if (Size >= 2) {
44         memcpy(&block_size, Data, 2);
45         block_size_ptr = &block_size;
46         Size -= 2;
47         Data += 2;
48     }
49     uint8_t* timeout_ptr = nullptr;
50     uint8_t timeout;
51     if (Size >= 1) {
52         memcpy(&timeout, Data, 1);
53         timeout_ptr = &timeout;
54         Size -= 1;
55         Data += 1;
56     }
57     uint16_t* window_size_ptr = nullptr;
58     uint16_t window_size;
59     if (Size >= 2) {
60         memcpy(&window_size, Data, 2);
61         window_size_ptr = &window_size;
62         Size -= 2;
63         Data += 2;
64     }
65     if (tftp_set_options(session, block_size_ptr, timeout_ptr, window_size_ptr) != TFTP_NO_ERROR) {
66         printf("tftp_set_options failed\n");
67         return 0;
68     }
69 
70     size_t scratch_size = 2048;
71     uint8_t scratch[2048];
72     uint32_t timeout_ms = 0;
73     tftp_process_msg(session, reinterpret_cast<void*>(const_cast<uint8_t*>(Data)), Size, scratch,
74             &scratch_size, &timeout_ms, nullptr);
75     return 0;
76 }
77