FreeRDP
Loading...
Searching...
No Matches
TestFuzzDrdynvc.c
1
6#include <stddef.h>
7#include <stdint.h>
8
9#include <winpr/stream.h>
10#include <winpr/wtypes.h>
11
12static UINT32 fuzz_var_uint_bytes(UINT8 cbLen)
13{
14 switch (cbLen)
15 {
16 case 0:
17 return 1;
18 case 1:
19 return 2;
20 default:
21 return 4;
22 }
23}
24
25static UINT32 fuzz_read_variable_uint(wStream* s, UINT8 cbLen)
26{
27 UINT32 value = 0;
28
29 switch (cbLen)
30 {
31 case 0:
32 value = Stream_Get_UINT8(s);
33 break;
34 case 1:
35 value = Stream_Get_UINT16(s);
36 break;
37 default:
38 value = Stream_Get_UINT32(s);
39 break;
40 }
41
42 return value;
43}
44
45enum
46{
47 CREATE_REQUEST_PDU = 0x01,
48 DATA_FIRST_PDU = 0x02,
49 DATA_PDU = 0x03,
50 CLOSE_REQUEST_PDU = 0x04,
51 CAPABILITY_REQUEST_PDU = 0x05,
52 DATA_FIRST_COMPRESSED_PDU = 0x06,
53 DATA_COMPRESSED_PDU = 0x07
54};
55
56static int fuzz_process_one_pdu(wStream* s)
57{
58 const size_t required = 1;
59
60 if (!Stream_CheckAndLogRequiredLength("fuzz", s, required))
61 return -1;
62
63 UINT8 header = Stream_Get_UINT8(s);
64 UINT8 command = (header & 0xf0) >> 4;
65 UINT8 spacing = (header & 0x0c) >> 2;
66 UINT8 cbChId = (header & 0x03);
67 size_t needed = fuzz_var_uint_bytes(cbChId);
68
69 switch (command)
70 {
71 case DATA_FIRST_PDU:
72 case DATA_FIRST_COMPRESSED_PDU:
73 if (!Stream_CheckAndLogRequiredLength("fuzz", s, needed + fuzz_var_uint_bytes(spacing)))
74 return -1;
75 (void)fuzz_read_variable_uint(s, cbChId);
76 (void)fuzz_read_variable_uint(s, spacing);
77 break;
78 case DATA_PDU:
79 case DATA_COMPRESSED_PDU:
80 case CLOSE_REQUEST_PDU:
81 case CREATE_REQUEST_PDU:
82 if (!Stream_CheckAndLogRequiredLength("fuzz", s, needed))
83 return -1;
84 (void)fuzz_read_variable_uint(s, cbChId);
85 break;
86 case CAPABILITY_REQUEST_PDU:
87 if (!Stream_CheckAndLogRequiredLength("fuzz", s, 2))
88 return -1;
89 Stream_Seek(s, 2);
90 break;
91 default:
92 break;
93 }
94
95 if (!Stream_CheckAndLogRequiredLength("fuzz", s, 2))
96 return -1;
97
98 {
99 size_t bodyLen = Stream_Get_UINT16(s);
100 const size_t remaining = Stream_GetRemainingLength(s);
101 if (bodyLen > remaining)
102 bodyLen = remaining;
103 Stream_Seek(s, bodyLen);
104 }
105
106 return 0;
107}
108
109int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
110{
111 if ((size == 0) || (size > (1u << 20)))
112 return 0;
113
114 wStream* s = Stream_New((BYTE*)data, size);
115 if (!s)
116 return 0;
117
118 for (size_t index = 0; index < 64; index++)
119 {
120 if (Stream_GetRemainingLength(s) == 0)
121 break;
122 if (fuzz_process_one_pdu(s) != 0)
123 break;
124 }
125
126 Stream_Free(s, FALSE);
127 return 0;
128}