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