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