1 /*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "osi/include/allocator.h"
18 #include "stack/include/avrc_api.h"
19
free_avrc_response(tAVRC_RESPONSE & result)20 static void free_avrc_response(tAVRC_RESPONSE& result) {
21 // AVRC_BldResponse
22 switch (result.pdu) {
23 case AVRC_PDU_NEXT_GROUP:
24 case AVRC_PDU_PREV_GROUP:
25 break;
26
27 case AVRC_PDU_GET_CAPABILITIES:
28 break;
29
30 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
31 break;
32
33 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
34 break;
35
36 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
37 osi_free_and_reset((void**)&result.get_cur_app_val.p_vals);
38 break;
39
40 case AVRC_PDU_SET_PLAYER_APP_VALUE:
41 break;
42
43 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
44 for (int i = 0; i < result.get_app_attr_txt.num_attr; i++) {
45 osi_free_and_reset((void**)&result.get_app_attr_txt.p_attrs[i].p_str);
46 }
47 osi_free_and_reset((void**)&result.get_app_attr_txt.p_attrs);
48 break;
49
50 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
51 for (int i = 0; i < result.get_app_val_txt.num_attr; i++) {
52 osi_free_and_reset((void**)&result.get_app_val_txt.p_attrs[i].p_str);
53 }
54 osi_free_and_reset((void**)&result.get_app_val_txt.p_attrs);
55 break;
56
57 case AVRC_PDU_INFORM_DISPLAY_CHARSET:
58 break;
59
60 case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
61 break;
62
63 case AVRC_PDU_GET_ELEMENT_ATTR:
64 for (int i = 0; i < result.get_attrs.num_attrs; i++) {
65 osi_free_and_reset((void**)&result.get_attrs.p_attrs[i].name.p_str);
66 }
67 osi_free_and_reset((void**)&result.get_attrs.p_attrs);
68 break;
69
70 case AVRC_PDU_GET_PLAY_STATUS:
71 break;
72
73 case AVRC_PDU_REGISTER_NOTIFICATION:
74 break;
75
76 case AVRC_PDU_REQUEST_CONTINUATION_RSP:
77 break;
78
79 case AVRC_PDU_ABORT_CONTINUATION_RSP:
80 break;
81
82 case AVRC_PDU_SET_ADDRESSED_PLAYER:
83 break;
84
85 case AVRC_PDU_PLAY_ITEM:
86 break;
87
88 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
89 break;
90
91 case AVRC_PDU_ADD_TO_NOW_PLAYING:
92 break;
93
94 case AVRC_PDU_SET_BROWSED_PLAYER:
95 for (int i = 0; i < result.br_player.folder_depth; i++) {
96 osi_free_and_reset((void**)&result.br_player.p_folders[i].p_str);
97 }
98 osi_free_and_reset((void**)&result.br_player.p_folders);
99 break;
100
101 case AVRC_PDU_GET_FOLDER_ITEMS:
102 for (int i = 0; i < result.get_items.item_count; i++) {
103 switch (result.get_items.p_item_list[i].item_type) {
104 case AVRC_ITEM_PLAYER:
105 osi_free_and_reset(
106 (void**)&result.get_items.p_item_list[i].u.player.name.p_str);
107 break;
108 case AVRC_ITEM_FOLDER:
109 osi_free_and_reset(
110 (void**)&result.get_items.p_item_list[i].u.folder.name.p_str);
111 break;
112 case AVRC_ITEM_MEDIA:
113 osi_free_and_reset(
114 (void**)&result.get_items.p_item_list[i].u.media.name.p_str);
115 for (int j = 0;
116 j < result.get_items.p_item_list[i].u.media.attr_count; j++) {
117 osi_free_and_reset((void**)&result.get_items.p_item_list[i]
118 .u.media.p_attr_list[j]
119 .name.p_str);
120 }
121 osi_free_and_reset(
122 (void**)&result.get_items.p_item_list[i].u.media.p_attr_list);
123 break;
124 }
125 }
126 osi_free_and_reset((void**)&result.get_items.p_item_list);
127 break;
128
129 case AVRC_PDU_CHANGE_PATH:
130 break;
131
132 case AVRC_PDU_GET_ITEM_ATTRIBUTES:
133 for (int i = 0; i < result.get_attrs.num_attrs; i++) {
134 osi_free_and_reset((void**)&result.get_attrs.p_attrs[i].name.p_str);
135 }
136 osi_free_and_reset((void**)&result.get_attrs.p_attrs);
137 break;
138
139 case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS:
140 break;
141
142 case AVRC_PDU_SEARCH:
143 break;
144 }
145 }
146
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)147 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
148 uint8_t scratch_buf[512]{};
149 uint16_t scratch_buf_len = 512;
150 tAVRC_MSG msg{};
151 tAVRC_RESPONSE result{};
152
153 if (size < 2) return 0;
154
155 /* 4 command type codes
156 * AVRC_CMD_CTRL 0
157 * AVRC_CMD_STATUS 1
158 * AVRC_CMD_SPEC_INQ 2
159 * AVRC_CMD_NOTIF 3
160 */
161 msg.hdr.ctype = data[0] % 4;
162
163 /* AVRC_Ctrl_ParsResponse handles opcode with AVRC_OP_VENDOR and
164 * AVRC_OP_BROWSE
165 * AVRC_ParsResponse handles opcode with AVRC_OP_VENDOR and
166 * AVRC_OP_PASS_THRU
167 * So we got 3 cases here */
168 switch (data[1] % 3) {
169 case 0:
170 msg.hdr.opcode = AVRC_OP_PASS_THRU;
171 msg.pass.p_pass_data = (uint8_t*)&data[2];
172 msg.pass.pass_len = size - 2;
173 break;
174 case 1:
175 msg.hdr.opcode = AVRC_OP_VENDOR;
176 msg.vendor.p_vendor_data = (uint8_t*)&data[2];
177 msg.vendor.vendor_len = size - 2;
178 break;
179 case 2:
180 msg.hdr.opcode = AVRC_OP_BROWSE;
181 msg.browse.p_browse_data = (uint8_t*)&data[2];
182 msg.browse.browse_len = size - 2;
183 break;
184 }
185
186 AVRC_Ctrl_ParsResponse(&msg, &result, scratch_buf, &scratch_buf_len);
187 free_avrc_response(result);
188
189 memset(&result, 0, sizeof(result));
190 AVRC_ParsResponse(&msg, &result, scratch_buf, scratch_buf_len);
191 free_avrc_response(result);
192
193 return 0;
194 }
195