greatscottgadgets / ubertooth

Software, firmware, and hardware designs for Ubertooth
https://greatscottgadgets.com/ubertoothone/
GNU General Public License v2.0
1.94k stars 433 forks source link

Assertion `caplen <= LE_MAX_PAYLOAD' failed when capturing BLE to pcap-ng with le_phy branch. #311

Closed Matir closed 6 years ago

Matir commented 6 years ago

It's not clear to me if this is an ubertooth or libbtbb bug, but I decided to report it here. Sorry if it's wrong. (Since it only happens with the le_phy branch here, I decided it's more likely either a firmware or tool bug in ubertooth than libbtbb.)

Steps to reproduce

  1. Build ubertooth firmware & tools from le_phy branch.
  2. Run ubertooth-btle against device: ubertooth-btle -rwatch_conn6.pcap -A37 -f -tE0:A0:30:C5:E8:58
  3. ubertooth-btle asserts and fails.

Reproducible 100% with the device I'm testing against (and whatever else is in the area on BLE). The assert only occurs when writing to a pcap-ng file, writing to legacy pcap formats seems fine.

Expected behaviour

ubertooth-btle should not crash and should capture packets.

Actual behaviour

ubertooth-btle asserts and dumps core with message: ubertooth-btle: /home/david/tmp/ble/libbtbb/lib/src/pcapng-bt.c:440: assemble_pcapng_le_packet: Assertion 'caplen <= LE_MAX_PAYLOAD' failed.

Version information

Operating system: Linux human 4.14.0-3-amd64 #1 SMP Debian 4.14.17-1 (2018-02-14) x86_64 GNU/Linux

Ubertooth tools version (ubertooth-rx -V): libubertooth 1.0 (git-84e3d01), libbtbb 1.0 (git-1b6084d)

libbtbb version: git-1b6084d

Ubertooth firmware version (ubertooth-util -v): ubertooth git-84e3d01 (david@human) Sat May 26 15:45:10 PDT 2018

Output

... Bunch of packets
ubertooth-btle: /home/david/tmp/ble/libbtbb/lib/src/pcapng-bt.c:440: assemble_pcapng_le_packet: Assertion `caplen <= LE_MAX_PAYLOAD' failed.
[1]    12754 abort (core dumped)

Backtrace and debugging data:

#0  __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007f1fca374231 in __GI_abort () at abort.c:79
#2  0x00007f1fca36b9da in __assert_fail_base (fmt=0x7f1fca4bed48 "%s%s%s:%u: %s%s"..., assertion=assertion@entry=0x7f1fcad5f375 "caplen <= LE_MA"..., file=file@entry=0x7f1fcad5f310 "/home/david/tmp"..., line=line@entry=0x1b8, function=function@entry=0x7f1fcad5f3b0 <__PRETTY_FUNCTION__.4365> "assemble_pcapng"...) at assert.c:92
#3  0x00007f1fca36ba52 in __GI___assert_fail (assertion=0x7f1fcad5f375 "caplen <= LE_MA"..., file=0x7f1fcad5f310 "/home/david/tmp"..., line=0x1b8, function=0x7f1fcad5f3b0 <__PRETTY_FUNCTION__.4365> "assemble_pcapng"...) at assert.c:101
#4  0x00007f1fcad56a3f in assemble_pcapng_le_packet (pkt=0x7ffc2d1da7d0, interface_id=0x0, ns=0x1532583acc3708ff, caplen=0x3e, rf_channel=0x0, signal_power=0xc0, noise_power=0x80, access_address_offenses=0x0, ref_access_address=0x8e89bed6, flags=0x37, lepkt=0x55c91aaf2440 "־\211\216B5\206께\231\032\002\001\033"...) at /home/david/tmp/ble/libbtbb/lib/src/pcapng-bt.c:440
#5  0x00007f1fcad56c29 in lell_pcapng_append_packet (h=0x55c91aadd2d0, ns=0x1532583acc3708ff, sigdbm=0xc0, noisedbm=0x80, refAA=0x8e89bed6, pkt=0x55c91aaf2440) at /home/david/tmp/ble/libbtbb/lib/src/pcapng-bt.c:475
#6  0x00007f1fcab3aea3 in cb_btle (ut=0x55c91aadd260, args=0x7ffc2d1da9a0) at /home/david/tmp/ble/ubertooth/host/libubertooth/src/ubertooth_callback.c:401
#7  0x000055c91a6ffb33 in main (argc=0x5, argv=0x7ffc2d1daad8) at /home/david/tmp/ble/ubertooth/host/ubertooth-tools/src/ubertooth-btle.c:273
#8  0x00007f1fca35fa87 in __libc_start_main (main=0x55c91a6ff5c6 <main>, argc=0x5, argv=0x7ffc2d1daad8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc2d1daac8) at ../csu/libc-start.c:310
#9  0x000055c91a6ff24a in _start ()

(from lell_pcapng_append_packet)
> info locals
flags = 0x37
pcapng_pkt = {
  blk_header = {
    block_type = 0x0, 
    block_total_length = 0x0, 
    interface_id = 0x2d1da810, 
    timestamp_high = 0x7ffc, 
    timestamp_low = 0x1a6ff220, 
    captured_len = 0x55c9, 
    packet_len = 0x2d1daad0, 
    packet_data = 0x7ffc2d1da7ec
  }, 
  le_ll_header = {
    rf_channel = 0xfc, 
    signal_power = 0x7f, 
    noise_power = 0x0, 
    access_address_offenses = 0x0, 
    ref_access_address = 0x0, 
    flags = 0x0, 
    le_packet = 0x7ffc2d1da7f6 ""
  }, 
  le_packet = "\000\000\377\322\324\312b\t\000\000\264\250\035-\374"..., 
  pad = "\000", 
  options = 0x2d1da8d8, 
  blk_tot_length = 0x7ffc
}
retval = 0x2d1da89e

(from cb_btle)
> info locals
info locals
pkt = 0x55c91aaf2440
opts = 0x7ffc2d1da9a0
i = 0x7f1f
usb = {
  pkt_type = 0x1, 
  status = 0x0, 
  channel = 0x0, 
  clkn_high = 0x0, 
  clk100ns = 0x5a0e9b77, 
  rssi_max = 0xf6, 
  rssi_min = 0xdc, 
  rssi_avg = 0x43, 
  rssi_count = 0x0, 
  reserved = "\000", 
  data = "־\211\216B5\206께\231\032\002\001\033\v\377L"...
}
rx = 0x7ffc2d1da890
prev_ts = 0x5a0b9bbe
refAA = 0x8e89bed6
sig = 0xc0
noise = 0x80
nowns = 0x1532583acc3708ff
rx_ts = 0xcab3dfa9
ts_diff = 0x0
len = 0x7ffc

The raw lell_packet struct as passed into lell_pcapng_append_packet:

$2 = {
  symbols = "־\211\216B5\206께\231\032\002\001\033\v\377L"..., 
  access_address = 0x8e89bed6, 
  channel_idx = 0x25, 
  channel_k = 0x0, 
  length = 0x35, 
  clk100ns = 0x5a0e9b77, 
  adv_type = 0x2, 
  adv_tx_add = 0x1, 
  adv_rx_add = 0x0, 
  access_address_offenses = 0x0, 
  refcount = 0x1, 
  flags = {
    as_bits = {
      access_address_ok = 0x1
    }, 
    as_word = 0x1
  }
}

And the contents of pkt->symbols in a hopefully useful format:

x/64bx pkt->symbols
0x55c91aaf2440: 0xd6    0xbe    0x89    0x8e    0x42    0x35    0x86    0xea
0x55c91aaf2448: 0xbb    0x98    0x99    0x1a    0x02    0x01    0x1b    0x0b
0x55c91aaf2450: 0xff    0x4c    0x00    0x09    0x06    0x03    0x20    0x2a
0x55c91aaf2458: 0x00    0x00    0x17    0xd1    0x66    0x7b    0xcb    0x95
0x55c91aaf2460: 0x4b    0xc4    0xd5    0x56    0xde    0x69    0x92    0x7b
0x55c91aaf2468: 0x49    0x4c    0xc1    0x43    0xcd    0x5f    0xf2    0x8d
0x55c91aaf2470: 0x04    0x1b    0x30    0xa9    0x1d    0x2d    0xfc    0x7f
0x55c91aaf2478: 0x00    0x00    0x40    0x24    0xaf    0x1a    0xc9    0x55

In the case of PCAP files, it seems to be truncated instead of the assert on pcapng. Again, not sure if this is a bug in libbtbb or in ubertooth-btle, since ubertooth-btle is passing the data in and it's being handled by libbtbb.

I can provide a core file directly as needed, but would rather not attach one to GitHub. Also happy to try to provide as much debug info as I can and/or try patches.

mikeryan commented 6 years ago

Thanks for the comprehensive bug report, saved a lot of back and forth.

The assertion is definitely inappropriate. In BT 4.2 and lower, maximum advertising length was 48 bytes. The smart behavior is to truncate and move along as in PCAP. For equivalent behavior, this code path should truncate.

However, as of BT 5.0 advertising packets can be up to 255 bytes. Therefore the correct fix is to allow full length packets. Expect a fix shortly.

mikeryan commented 6 years ago

Try the long_packet branch of libbtbb and see if your captures look correct.

Matir commented 6 years ago

Sorry for the delay -- that branch definitely does allow capturing longer advertisements (seeing 53 octets), so it looks like it fixes this issue.

mikeryan commented 6 years ago

Would you be willing to share the ubertooth-btle output and a sample PcapNG with the long advertising packet? I haven't seen one in the wild and would like to make sure the rest of the toolchain supports it correctly. Totally understand if you can't share.

Matir commented 6 years ago

Sent directly to the email from which you committed the fix into libbtbb. Didn't want to post on Github.

On Sun, May 27, 2018 at 11:11 AM Mike Ryan notifications@github.com wrote:

Would you be willing to share the ubertooth-btle output and a sample PcapNG with the long advertising packet? I haven't seen one in the wild and would like to make sure the rest of the toolchain supports it correctly. Totally understand if you can't share.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/greatscottgadgets/ubertooth/issues/311#issuecomment-392351983, or mute the thread https://github.com/notifications/unsubscribe-auth/AAxYAFaF8qtOAxue_RCzhGyK1d8DXfG-ks5t2uxmgaJpZM4UPGmf .

-- David Tomaschik https://systemoverlord.com david@systemoverlord.com 7FD5 8D9A 196D CEEE AD67 1F94 F4D7 A791 5DEA 789B

mikeryan commented 6 years ago

Received and verified that the packet in question was the victim of bitflips, including the length field in the LL header. The assert behavior in libbtbb was not correct, so I will still merge the fix into libbtbb master. Thanks for reporting!