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