1 /******************************************************************************
2 *
3 * Copyright 2014 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_snoop"
20
21 #include <mutex>
22
23 #include <arpa/inet.h>
24 #include <base/logging.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <inttypes.h>
28 #include <limits.h>
29 #include <netinet/in.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 #include <sys/uio.h>
37 #include <unistd.h>
38 #include <mutex>
39 #include <unordered_map>
40 #include <unordered_set>
41
42 #include "bt_types.h"
43 #include "common/time_util.h"
44 #include "hci/include/btsnoop.h"
45 #include "hci/include/btsnoop_mem.h"
46 #include "hci_layer.h"
47 #include "internal_include/bt_trace.h"
48 #include "osi/include/log.h"
49 #include "osi/include/properties.h"
50 #include "stack/include/hcimsgs.h"
51 #include "stack/include/rfcdefs.h"
52 #include "stack/l2cap/l2c_int.h"
53 #include "stack_config.h"
54 #include "main/shim/shim.h"
55
56 // The number of of packets per btsnoop file before we rotate to the next
57 // file. As of right now there are two snoop files that are rotated through.
58 // The size can be dynamically configured by seting the relevant system
59 // property
60 #define DEFAULT_BTSNOOP_SIZE 0xffff
61
62 #define IS_DEBUGGABLE_PROPERTY "ro.debuggable"
63
64 #define BTSNOOP_LOG_MODE_PROPERTY "persist.bluetooth.btsnooplogmode"
65 #define BTSNOOP_DEFAULT_MODE_PROPERTY "persist.bluetooth.btsnoopdefaultmode"
66 #define BTSNOOP_MODE_DISABLED "disabled"
67 #define BTSNOOP_MODE_FILTERED "filtered"
68 #define BTSNOOP_MODE_FULL "full"
69
70 #define BTSNOOP_PATH_PROPERTY "persist.bluetooth.btsnooppath"
71 #define DEFAULT_BTSNOOP_PATH "/data/misc/bluetooth/logs/btsnoop_hci.log"
72 #define BTSNOOP_MAX_PACKETS_PROPERTY "persist.bluetooth.btsnoopsize"
73
74 typedef enum {
75 kCommandPacket = 1,
76 kAclPacket = 2,
77 kScoPacket = 3,
78 kEventPacket = 4,
79 kIsoPacket = 5,
80 } packet_type_t;
81
82 // Epoch in microseconds since 01/01/0000
83 static const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL;
84
85 // Number of bytes into a packet where you can find the value for a channel.
86 static const size_t ACL_CHANNEL_OFFSET = 0;
87 static const size_t L2C_CHANNEL_OFFSET = 6;
88 static const size_t RFC_CHANNEL_OFFSET = 8;
89 static const size_t RFC_EVENT_OFFSET = 9;
90
91 // The size of the L2CAP header. All information past this point is removed from
92 // a filtered packet.
93 static const uint32_t L2C_HEADER_SIZE = 9;
94
95 static int logfile_fd = INVALID_FD;
96 static std::mutex btsnoop_mutex;
97
98 static int32_t packets_per_file;
99 static int32_t packet_counter;
100
101 // Channel tracking variables for filtering.
102
103 // Keeps track of L2CAP channels that need to be filtered out of the snoop
104 // logs.
105 class FilterTracker {
106 public:
107 // NOTE: 1 is used as a static CID for L2CAP signaling
108 std::unordered_set<uint16_t> l2c_local_cid = {1};
109 std::unordered_set<uint16_t> l2c_remote_cid = {1};
110 uint16_t rfc_local_cid = 0;
111 uint16_t rfc_remote_cid = 0;
112 std::unordered_set<uint16_t> rfc_channels = {0};
113
114 // Adds L2C channel to allowlist.
addL2cCid(uint16_t local_cid,uint16_t remote_cid)115 void addL2cCid(uint16_t local_cid, uint16_t remote_cid) {
116 l2c_local_cid.insert(local_cid);
117 l2c_remote_cid.insert(remote_cid);
118 }
119
120 // Sets L2CAP channel that RFCOMM uses.
setRfcCid(uint16_t local_cid,uint16_t remote_cid)121 void setRfcCid(uint16_t local_cid, uint16_t remote_cid) {
122 rfc_local_cid = local_cid;
123 rfc_remote_cid = remote_cid;
124 }
125
126 // Remove L2C channel from allowlist.
removeL2cCid(uint16_t local_cid,uint16_t remote_cid)127 void removeL2cCid(uint16_t local_cid, uint16_t remote_cid) {
128 if (rfc_local_cid == local_cid) {
129 rfc_channels.clear();
130 rfc_channels.insert(0);
131 rfc_local_cid = 0;
132 rfc_remote_cid = 0;
133 }
134
135 l2c_local_cid.erase(local_cid);
136 l2c_remote_cid.erase(remote_cid);
137 }
138
addRfcDlci(uint8_t channel)139 void addRfcDlci(uint8_t channel) { rfc_channels.insert(channel); }
140
isAllowlistedL2c(bool local,uint16_t cid)141 bool isAllowlistedL2c(bool local, uint16_t cid) {
142 const auto& set = local ? l2c_local_cid : l2c_remote_cid;
143 return (set.find(cid) != set.end());
144 }
145
isRfcChannel(bool local,uint16_t cid)146 bool isRfcChannel(bool local, uint16_t cid) {
147 const auto& channel = local ? rfc_local_cid : rfc_remote_cid;
148 return cid == channel;
149 }
150
isAllowlistedDlci(uint8_t dlci)151 bool isAllowlistedDlci(uint8_t dlci) {
152 return rfc_channels.find(dlci) != rfc_channels.end();
153 }
154 };
155
156 std::mutex filter_list_mutex;
157 std::unordered_map<uint16_t, FilterTracker> filter_list;
158 std::unordered_map<uint16_t, uint16_t> local_cid_to_acl;
159
160 // Cached value for whether full snoop logs are enabled. So the property isn't
161 // checked for every packet.
162 static bool is_btsnoop_enabled;
163 static bool is_btsnoop_filtered;
164
165 // TODO(zachoverflow): merge btsnoop and btsnoop_net together
166 void btsnoop_net_open();
167 void btsnoop_net_close();
168 void btsnoop_net_write(const void* data, size_t length);
169
170 static void delete_btsnoop_files(bool filtered);
171 static std::string get_btsnoop_log_path(bool filtered);
172 static std::string get_btsnoop_last_log_path(std::string log_path);
173 static void open_next_snoop_file();
174 static void btsnoop_write_packet(packet_type_t type, uint8_t* packet,
175 bool is_received, uint64_t timestamp_us);
176
177 // Module lifecycle functions
178
start_up()179 static future_t* start_up() {
180 std::array<char, PROPERTY_VALUE_MAX> property = {};
181 std::lock_guard<std::mutex> lock(btsnoop_mutex);
182
183 // Default mode is FILTERED on userdebug/eng build, DISABLED on user build.
184 // It can also be overwritten by modifying the global setting.
185 int is_debuggable = osi_property_get_int32(IS_DEBUGGABLE_PROPERTY, 0);
186 std::string default_mode = BTSNOOP_MODE_DISABLED;
187 if (is_debuggable) {
188 int len = osi_property_get(BTSNOOP_DEFAULT_MODE_PROPERTY, property.data(),
189 BTSNOOP_MODE_DISABLED);
190 default_mode = std::string(property.data(), len);
191 }
192
193 // Get the actual mode
194 int len = osi_property_get(BTSNOOP_LOG_MODE_PROPERTY, property.data(),
195 default_mode.c_str());
196 std::string btsnoop_mode(property.data(), len);
197
198 if (btsnoop_mode == BTSNOOP_MODE_FILTERED) {
199 LOG(INFO) << __func__ << ": Filtered Snoop Logs enabled";
200 is_btsnoop_enabled = true;
201 is_btsnoop_filtered = true;
202 delete_btsnoop_files(false);
203 } else if (btsnoop_mode == BTSNOOP_MODE_FULL) {
204 LOG(INFO) << __func__ << ": Snoop Logs fully enabled";
205 is_btsnoop_enabled = true;
206 is_btsnoop_filtered = false;
207 delete_btsnoop_files(true);
208 } else {
209 LOG(INFO) << __func__ << ": Snoop Logs disabled";
210 is_btsnoop_enabled = false;
211 is_btsnoop_filtered = false;
212 delete_btsnoop_files(true);
213 delete_btsnoop_files(false);
214 }
215
216 if (is_btsnoop_enabled) {
217 open_next_snoop_file();
218 packets_per_file = osi_property_get_int32(BTSNOOP_MAX_PACKETS_PROPERTY,
219 DEFAULT_BTSNOOP_SIZE);
220 btsnoop_net_open();
221 }
222
223 return NULL;
224 }
225
shut_down(void)226 static future_t* shut_down(void) {
227 std::lock_guard<std::mutex> lock(btsnoop_mutex);
228
229 if (is_btsnoop_enabled) {
230 if (is_btsnoop_filtered) {
231 delete_btsnoop_files(false);
232 } else {
233 delete_btsnoop_files(true);
234 }
235 } else {
236 delete_btsnoop_files(true);
237 delete_btsnoop_files(false);
238 }
239
240 if (logfile_fd != INVALID_FD) close(logfile_fd);
241 logfile_fd = INVALID_FD;
242
243 if (is_btsnoop_enabled) btsnoop_net_close();
244
245 return NULL;
246 }
247
248 EXPORT_SYMBOL extern const module_t btsnoop_module = {
249 .name = BTSNOOP_MODULE,
250 .init = NULL,
251 .start_up = start_up,
252 .shut_down = shut_down,
253 .clean_up = NULL,
254 .dependencies = {STACK_CONFIG_MODULE, NULL}};
255
256 // Interface functions
capture(const BT_HDR * buffer,bool is_received)257 static void capture(const BT_HDR* buffer, bool is_received) {
258 uint8_t* p = const_cast<uint8_t*>(buffer->data + buffer->offset);
259
260 std::lock_guard<std::mutex> lock(btsnoop_mutex);
261
262 struct timespec ts_now = {};
263 clock_gettime(CLOCK_REALTIME, &ts_now);
264 uint64_t timestamp_us =
265 ((uint64_t)ts_now.tv_sec * 1000000L) + ((uint64_t)ts_now.tv_nsec / 1000);
266
267 btsnoop_mem_capture(buffer, timestamp_us);
268
269 if (logfile_fd == INVALID_FD) return;
270
271 switch (buffer->event & MSG_EVT_MASK) {
272 case MSG_HC_TO_STACK_HCI_EVT:
273 btsnoop_write_packet(kEventPacket, p, false, timestamp_us);
274 break;
275 case MSG_HC_TO_STACK_HCI_ACL:
276 case MSG_STACK_TO_HC_HCI_ACL:
277 btsnoop_write_packet(kAclPacket, p, is_received, timestamp_us);
278 break;
279 case MSG_HC_TO_STACK_HCI_SCO:
280 case MSG_STACK_TO_HC_HCI_SCO:
281 btsnoop_write_packet(kScoPacket, p, is_received, timestamp_us);
282 break;
283 case MSG_STACK_TO_HC_HCI_CMD:
284 btsnoop_write_packet(kCommandPacket, p, true, timestamp_us);
285 break;
286 case MSG_HC_TO_STACK_HCI_ISO:
287 case MSG_STACK_TO_HC_HCI_ISO:
288 btsnoop_write_packet(kIsoPacket, p, is_received, timestamp_us);
289 break;
290 }
291 }
292
allowlist_l2c_channel(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)293 static void allowlist_l2c_channel(uint16_t conn_handle, uint16_t local_cid,
294 uint16_t remote_cid) {
295 LOG(INFO) << __func__
296 << ": Allowlisting l2cap channel. conn_handle=" << conn_handle
297 << " cid=" << loghex(local_cid) << ":" << loghex(remote_cid);
298 if (bluetooth::shim::is_any_gd_enabled()) {
299 return;
300 }
301 std::lock_guard lock(filter_list_mutex);
302
303 // This will create the entry if there is no associated filter with the
304 // connection.
305 filter_list[conn_handle].addL2cCid(local_cid, remote_cid);
306 }
307
allowlist_rfc_dlci(uint16_t local_cid,uint8_t dlci)308 static void allowlist_rfc_dlci(uint16_t local_cid, uint8_t dlci) {
309 LOG(INFO) << __func__
310 << ": Allowlisting rfcomm channel. L2CAP CID=" << loghex(local_cid)
311 << " DLCI=" << loghex(dlci);
312 if (bluetooth::shim::is_any_gd_enabled()) {
313 return;
314 }
315 std::lock_guard lock(filter_list_mutex);
316
317 tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(nullptr, local_cid);
318 filter_list[p_ccb->p_lcb->Handle()].addRfcDlci(dlci);
319 }
320
add_rfc_l2c_channel(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)321 static void add_rfc_l2c_channel(uint16_t conn_handle, uint16_t local_cid,
322 uint16_t remote_cid) {
323 LOG(INFO) << __func__
324 << ": rfcomm data going over l2cap channel. conn_handle="
325 << conn_handle << " cid=" << loghex(local_cid) << ":"
326 << loghex(remote_cid);
327 if (bluetooth::shim::is_any_gd_enabled()) {
328 return;
329 }
330 std::lock_guard lock(filter_list_mutex);
331
332 filter_list[conn_handle].setRfcCid(local_cid, remote_cid);
333 local_cid_to_acl.insert({local_cid, conn_handle});
334 }
335
clear_l2cap_allowlist(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)336 static void clear_l2cap_allowlist(uint16_t conn_handle, uint16_t local_cid,
337 uint16_t remote_cid) {
338 LOG(INFO) << __func__
339 << ": Clearing acceptlist from l2cap channel. conn_handle="
340 << conn_handle << " cid=" << local_cid << ":" << remote_cid;
341
342 if (bluetooth::shim::is_any_gd_enabled()) {
343 return;
344 }
345 std::lock_guard lock(filter_list_mutex);
346 filter_list[conn_handle].removeL2cCid(local_cid, remote_cid);
347 }
348
349 static const btsnoop_t interface = {capture, allowlist_l2c_channel,
350 allowlist_rfc_dlci, add_rfc_l2c_channel,
351 clear_l2cap_allowlist};
352
btsnoop_get_interface()353 const btsnoop_t* btsnoop_get_interface() { return &interface; }
354
delete_btsnoop_files(bool filtered)355 static void delete_btsnoop_files(bool filtered) {
356 LOG(INFO) << __func__
357 << ": Deleting snoop logs if they exist. filtered = " << filtered;
358 auto log_path = get_btsnoop_log_path(filtered);
359 remove(log_path.c_str());
360 remove(get_btsnoop_last_log_path(log_path).c_str());
361 }
362
get_btsnoop_log_path(bool filtered)363 std::string get_btsnoop_log_path(bool filtered) {
364 char btsnoop_path[PROPERTY_VALUE_MAX];
365 osi_property_get(BTSNOOP_PATH_PROPERTY, btsnoop_path, DEFAULT_BTSNOOP_PATH);
366 std::string result(btsnoop_path);
367 if (filtered) result = result.append(".filtered");
368
369 return result;
370 }
371
get_btsnoop_last_log_path(std::string btsnoop_path)372 std::string get_btsnoop_last_log_path(std::string btsnoop_path) {
373 return btsnoop_path.append(".last");
374 }
375
open_next_snoop_file()376 static void open_next_snoop_file() {
377 packet_counter = 0;
378
379 if (logfile_fd != INVALID_FD) {
380 close(logfile_fd);
381 logfile_fd = INVALID_FD;
382 }
383
384 auto log_path = get_btsnoop_log_path(is_btsnoop_filtered);
385 auto last_log_path = get_btsnoop_last_log_path(log_path);
386
387 if (rename(log_path.c_str(), last_log_path.c_str()) != 0 && errno != ENOENT)
388 LOG(ERROR) << __func__ << ": unable to rename '" << log_path << "' to '"
389 << last_log_path << "' : " << strerror(errno);
390
391 mode_t prevmask = umask(0);
392 logfile_fd = open(log_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
393 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
394 umask(prevmask);
395 if (logfile_fd == INVALID_FD) {
396 LOG(ERROR) << __func__ << ": unable to open '" << log_path
397 << "' : " << strerror(errno);
398 return;
399 }
400
401 (void)write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
402 }
403
404 typedef struct {
405 uint32_t length_original;
406 uint32_t length_captured;
407 uint32_t flags;
408 uint32_t dropped_packets;
409 uint64_t timestamp;
410 uint8_t type;
411 } __attribute__((__packed__)) btsnoop_header_t;
412
htonll(uint64_t ll)413 static uint64_t htonll(uint64_t ll) {
414 const uint32_t l = 1;
415 if (*(reinterpret_cast<const uint8_t*>(&l)) == 1)
416 return static_cast<uint64_t>(htonl(ll & 0xffffffff)) << 32 |
417 htonl(ll >> 32);
418
419 return ll;
420 }
421
should_filter_log(bool is_received,uint8_t * packet)422 static bool should_filter_log(bool is_received, uint8_t* packet) {
423 uint16_t acl_handle =
424 HCID_GET_HANDLE((((uint16_t)packet[ACL_CHANNEL_OFFSET + 1]) << 8) +
425 packet[ACL_CHANNEL_OFFSET]);
426
427 std::lock_guard lock(filter_list_mutex);
428 auto& filters = filter_list[acl_handle];
429 uint16_t l2c_channel =
430 (packet[L2C_CHANNEL_OFFSET + 1] << 8) + packet[L2C_CHANNEL_OFFSET];
431 if (filters.isRfcChannel(is_received, l2c_channel)) {
432 uint8_t rfc_event = packet[RFC_EVENT_OFFSET] & 0b11101111;
433 if (rfc_event == RFCOMM_SABME || rfc_event == RFCOMM_UA) {
434 return false;
435 }
436
437 uint8_t rfc_dlci = packet[RFC_CHANNEL_OFFSET] >> 2;
438 if (!filters.isAllowlistedDlci(rfc_dlci)) {
439 return true;
440 }
441 } else if (!filters.isAllowlistedL2c(is_received, l2c_channel)) {
442 return true;
443 }
444
445 return false;
446 }
447
btsnoop_write_packet(packet_type_t type,uint8_t * packet,bool is_received,uint64_t timestamp_us)448 static void btsnoop_write_packet(packet_type_t type, uint8_t* packet,
449 bool is_received, uint64_t timestamp_us) {
450 uint32_t length_he = 0;
451 uint32_t flags = 0;
452
453 switch (type) {
454 case kCommandPacket:
455 length_he = packet[2] + 4;
456 flags = 2;
457 break;
458 case kAclPacket:
459 length_he = (packet[3] << 8) + packet[2] + 5;
460 flags = is_received;
461 break;
462 case kScoPacket:
463 length_he = packet[2] + 4;
464 flags = is_received;
465 break;
466 case kEventPacket:
467 length_he = packet[1] + 3;
468 flags = 3;
469 break;
470 case kIsoPacket:
471 length_he = ((packet[3] & 0x3f) << 8) + packet[2] + 5;
472 flags = is_received;
473 break;
474 }
475
476 btsnoop_header_t header;
477 header.length_original = htonl(length_he);
478
479 bool rejectlisted = false;
480 if (is_btsnoop_filtered && type == kAclPacket) {
481 rejectlisted = should_filter_log(is_received, packet);
482 }
483
484 header.length_captured =
485 rejectlisted ? htonl(L2C_HEADER_SIZE) : header.length_original;
486 if (rejectlisted) length_he = L2C_HEADER_SIZE;
487 header.flags = htonl(flags);
488 header.dropped_packets = 0;
489 header.timestamp = htonll(timestamp_us + BTSNOOP_EPOCH_DELTA);
490 header.type = type;
491
492 btsnoop_net_write(&header, sizeof(btsnoop_header_t));
493 btsnoop_net_write(packet, length_he - 1);
494
495 if (logfile_fd != INVALID_FD) {
496 packet_counter++;
497 if (packet_counter > packets_per_file) {
498 open_next_snoop_file();
499 }
500
501 iovec iov[] = {{&header, sizeof(btsnoop_header_t)},
502 {reinterpret_cast<void*>(packet), length_he - 1}};
503 TEMP_FAILURE_RETRY(writev(logfile_fd, iov, 2));
504 }
505 }
506