1 /*
2  * Copyright 2020 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 "hci/fuzz/fuzz_hci_layer.h"
18 
19 #include "fuzz/helpers.h"
20 #include "hci/class_of_device.h"
21 
22 namespace bluetooth {
23 namespace hci {
24 namespace fuzz {
25 
26 using bluetooth::common::ContextualCallback;
27 using bluetooth::fuzz::GetArbitraryBytes;
28 using bluetooth::fuzz::InvokeIfValid;
29 
GetSecurityInterface(ContextualCallback<void (hci::EventView)>)30 hci::SecurityInterface* FuzzHciLayer::GetSecurityInterface(
31         ContextualCallback<void(hci::EventView)> /* event_handler */) {
32   return &security_interface_;
33 }
34 
GetLeSecurityInterface(ContextualCallback<void (hci::LeMetaEventView)>)35 hci::LeSecurityInterface* FuzzHciLayer::GetLeSecurityInterface(
36         ContextualCallback<void(hci::LeMetaEventView)> /* event_handler */) {
37   return &le_security_interface_;
38 }
39 
GetAclConnectionInterface(ContextualCallback<void (hci::EventView)>,ContextualCallback<void (uint16_t,hci::ErrorCode)>,ContextualCallback<void (Address,ClassOfDevice)>,ContextualCallback<void (hci::ErrorCode,uint16_t,uint8_t version,uint16_t manufacturer_name,uint16_t sub_version)>)40 hci::AclConnectionInterface* FuzzHciLayer::GetAclConnectionInterface(
41         ContextualCallback<void(hci::EventView)> /* event_handler */,
42         ContextualCallback<void(uint16_t, hci::ErrorCode)> /* on_disconnect */,
43         ContextualCallback<void(Address, ClassOfDevice)> /* on_connection_request */,
44         ContextualCallback<void(hci::ErrorCode, uint16_t, uint8_t version,
45                                 uint16_t manufacturer_name, uint16_t sub_version)>
46         /* on_read_remote_version */) {
47   return &acl_connection_interface_;
48 }
49 
GetLeAclConnectionInterface(ContextualCallback<void (hci::LeMetaEventView)>,ContextualCallback<void (uint16_t,hci::ErrorCode)>,ContextualCallback<void (hci::ErrorCode,uint16_t,uint8_t version,uint16_t manufacturer_name,uint16_t sub_version)>)50 hci::LeAclConnectionInterface* FuzzHciLayer::GetLeAclConnectionInterface(
51         ContextualCallback<void(hci::LeMetaEventView)> /* event_handler */,
52         ContextualCallback<void(uint16_t, hci::ErrorCode)> /* on_disconnect */,
53         ContextualCallback<void(hci::ErrorCode, uint16_t, uint8_t version,
54                                 uint16_t manufacturer_name, uint16_t sub_version)>
55         /* on_read_remote_version */) {
56   return &le_acl_connection_interface_;
57 }
58 
GetLeAdvertisingInterface(ContextualCallback<void (hci::LeMetaEventView)>)59 hci::LeAdvertisingInterface* FuzzHciLayer::GetLeAdvertisingInterface(
60         ContextualCallback<void(hci::LeMetaEventView)> /* event_handler */) {
61   return &le_advertising_interface_;
62 }
63 
GetLeScanningInterface(ContextualCallback<void (hci::LeMetaEventView)>)64 hci::LeScanningInterface* FuzzHciLayer::GetLeScanningInterface(
65         ContextualCallback<void(hci::LeMetaEventView)> /* event_handler */) {
66   return &le_scanning_interface_;
67 }
68 
GetLeIsoInterface(ContextualCallback<void (hci::LeMetaEventView)>)69 hci::LeIsoInterface* FuzzHciLayer::GetLeIsoInterface(
70         ContextualCallback<void(hci::LeMetaEventView)> /* event_handler */) {
71   return &le_iso_interface_;
72 }
73 
GetDistanceMeasurementInterface(ContextualCallback<void (hci::LeMetaEventView)>)74 hci::DistanceMeasurementInterface* FuzzHciLayer::GetDistanceMeasurementInterface(
75         ContextualCallback<void(hci::LeMetaEventView)> /* event_handler */) {
76   return &distance_measurement_interface_;
77 }
78 
Start()79 void FuzzHciLayer::Start() {
80   acl_dev_null_ = new os::fuzz::DevNullQueue<AclBuilder>(acl_queue_.GetDownEnd(), GetHandler());
81   acl_dev_null_->Start();
82   acl_inject_ = new os::fuzz::FuzzInjectQueue<AclView>(acl_queue_.GetDownEnd(), GetHandler());
83 }
84 
Stop()85 void FuzzHciLayer::Stop() {
86   acl_dev_null_->Stop();
87   delete acl_dev_null_;
88   delete acl_inject_;
89 }
90 
injectArbitrary(FuzzedDataProvider & fdp)91 void FuzzHciLayer::injectArbitrary(FuzzedDataProvider& fdp) {
92   const uint8_t action = fdp.ConsumeIntegralInRange(0, 13);
93   switch (action) {
94     case 1:
95       injectAclData(GetArbitraryBytes(&fdp));
96       break;
97     case 2:
98       injectCommandComplete(GetArbitraryBytes(&fdp));
99       break;
100     case 3:
101       injectCommandStatus(GetArbitraryBytes(&fdp));
102       break;
103     case 4:
104       injectEvent(fdp);
105       break;
106     case 5:
107       injectLeEvent(fdp);
108       break;
109     case 6:
110       injectSecurityEvent(GetArbitraryBytes(&fdp));
111       break;
112     case 7:
113       injectLeSecurityEvent(GetArbitraryBytes(&fdp));
114       break;
115     case 8:
116       injectAclEvent(GetArbitraryBytes(&fdp));
117       break;
118     case 9:
119       injectAclDisconnect(fdp);
120       break;
121     case 10:
122       injectLeAclEvent(GetArbitraryBytes(&fdp));
123       break;
124     case 11:
125       injectLeAclDisconnect(fdp);
126       break;
127     case 12:
128       injectLeAdvertisingEvent(GetArbitraryBytes(&fdp));
129       break;
130     case 13:
131       injectLeScanningEvent(GetArbitraryBytes(&fdp));
132       break;
133   }
134 }
135 
injectAclData(std::vector<uint8_t> data)136 void FuzzHciLayer::injectAclData(std::vector<uint8_t> data) {
137   CONSTRUCT_VALID_UNIQUE_OTHERWISE_BAIL(hci::AclView, packet, data);
138   acl_inject_->Inject(std::move(packet));
139 }
140 
injectCommandComplete(std::vector<uint8_t> data)141 void FuzzHciLayer::injectCommandComplete(std::vector<uint8_t> data) {
142   InvokeIfValid<hci::CommandCompleteView>(std::move(on_command_complete_), data);
143 }
144 
injectCommandStatus(std::vector<uint8_t> data)145 void FuzzHciLayer::injectCommandStatus(std::vector<uint8_t> data) {
146   InvokeIfValid<hci::CommandStatusView>(std::move(on_command_status_), data);
147 }
148 
injectEvent(FuzzedDataProvider & fdp)149 void FuzzHciLayer::injectEvent(FuzzedDataProvider& fdp) {
150   auto handler_pair = event_handlers_.find(static_cast<EventCode>(fdp.ConsumeIntegral<uint8_t>()));
151   if (handler_pair != event_handlers_.end()) {
152     InvokeIfValid<EventView>(handler_pair->second, GetArbitraryBytes(&fdp));
153   }
154 }
155 
injectLeEvent(FuzzedDataProvider & fdp)156 void FuzzHciLayer::injectLeEvent(FuzzedDataProvider& fdp) {
157   auto handler_pair =
158           le_event_handlers_.find(static_cast<SubeventCode>(fdp.ConsumeIntegral<uint8_t>()));
159   if (handler_pair != le_event_handlers_.end()) {
160     InvokeIfValid<LeMetaEventView>(handler_pair->second, GetArbitraryBytes(&fdp));
161   }
162 }
163 
injectSecurityEvent(std::vector<uint8_t> data)164 void FuzzHciLayer::injectSecurityEvent(std::vector<uint8_t> data) {
165   InvokeIfValid<EventView>(security_event_handler_, data);
166 }
167 
injectLeSecurityEvent(std::vector<uint8_t> data)168 void FuzzHciLayer::injectLeSecurityEvent(std::vector<uint8_t> data) {
169   InvokeIfValid<LeMetaEventView>(le_security_event_handler_, data);
170 }
171 
injectAclEvent(std::vector<uint8_t> data)172 void FuzzHciLayer::injectAclEvent(std::vector<uint8_t> data) {
173   InvokeIfValid<EventView>(acl_event_handler_, data);
174 }
175 
injectAclDisconnect(FuzzedDataProvider & fdp)176 void FuzzHciLayer::injectAclDisconnect(FuzzedDataProvider& fdp) {
177   if (acl_on_disconnect_) {
178     acl_on_disconnect_(fdp.ConsumeIntegral<uint16_t>(),
179                        static_cast<hci::ErrorCode>(fdp.ConsumeIntegral<uint8_t>()));
180   }
181 }
182 
injectLeAclEvent(std::vector<uint8_t> data)183 void FuzzHciLayer::injectLeAclEvent(std::vector<uint8_t> data) {
184   InvokeIfValid<LeMetaEventView>(le_acl_event_handler_, data);
185 }
186 
injectLeAclDisconnect(FuzzedDataProvider & fdp)187 void FuzzHciLayer::injectLeAclDisconnect(FuzzedDataProvider& fdp) {
188   if (le_acl_on_disconnect_) {
189     le_acl_on_disconnect_(fdp.ConsumeIntegral<uint16_t>(),
190                           static_cast<hci::ErrorCode>(fdp.ConsumeIntegral<uint8_t>()));
191   }
192 }
193 
injectLeAdvertisingEvent(std::vector<uint8_t> data)194 void FuzzHciLayer::injectLeAdvertisingEvent(std::vector<uint8_t> data) {
195   InvokeIfValid<LeMetaEventView>(le_advertising_event_handler_, data);
196 }
197 
injectLeScanningEvent(std::vector<uint8_t> data)198 void FuzzHciLayer::injectLeScanningEvent(std::vector<uint8_t> data) {
199   InvokeIfValid<LeMetaEventView>(le_scanning_event_handler_, data);
200 }
201 
injectLeIsoEvent(std::vector<uint8_t> data)202 void FuzzHciLayer::injectLeIsoEvent(std::vector<uint8_t> data) {
203   InvokeIfValid<LeMetaEventView>(le_iso_event_handler_, data);
204 }
205 
__anon02a2ead10102() 206 const ModuleFactory FuzzHciLayer::Factory = ModuleFactory([]() { return new FuzzHciLayer(); });
207 
208 }  // namespace fuzz
209 }  // namespace hci
210 }  // namespace bluetooth
211