Fix stack-buffer-overflow in bluetooth service GATT client

Use the tBTA_GATTC union for |notify| in bta_gattc_process_indicate() to
avoid a stack-buffer-overflow in btif_transfer_context.

==1410==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x0077c8c0c066 at pc 0x0077e50c9ae0 bp 0x0077c8c0bcd0 sp 0x0077c8c0b460

READ of size 616 at 0x0077c8c0c066 thread T38 (btu message loo)
    #0 0x77e50c9adf in __interceptor_memcpy external/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc:701:5
    #1 0x77ca1e838f in memcpy(void*, void const* pass_object_size0, unsigned long) bionic/libc/include/string.h:173:12
    #2 0x77ca1e838f in btif_transfer_context(void (*)(unsigned short, char*), unsigned short, char*, int, void (*)(unsigned short, char*, char*)) system/bt/btif/src/btif_core.cc:208:0
    #3 0x77ca209853 in (anonymous namespace)::bta_gattc_cback(unsigned char, tBTA_GATTC*) system/bt/btif/src/btif_gatt_client.cc:204:7
    #4 0x77ca11455b in bta_gattc_process_indicate(unsigned short, unsigned char, tGATT_CL_COMPLETE*) system/bt/bta/gatt/bta_gattc_act.cc:1596:9
    #5 0x77ca40b4b7 in gatt_process_notification(tGATT_TCB&, unsigned char, unsigned short, unsigned char*) system/bt/stack/gatt/gatt_cl.cc:664:7
    #6 0x77ca40d78f in gatt_client_handle_server_rsp(tGATT_TCB&, unsigned char, unsigned short, unsigned char*) system/bt/stack/gatt/gatt_cl.cc:1119:9
    #7 0x77ca414447 in gatt_le_data_ind(unsigned short, unsigned char*, BT_HDR*) system/bt/stack/gatt/gatt_main.cc:576:7
    #8 0x77ca47665b in l2c_rcv_acl_data(BT_HDR*) system/bt/stack/l2cap/l2c_main.cc:211:9
    #9 0x77c9da50eb in base::Callback<void (), (base::internal::CopyMode)1>::Run() const external/libchrome/base/callback.h:389:12
    #10 0x77c9da50eb in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask const&) external/libchrome/base/debug/task_annotator.cc:51:0
    #11 0x77c9df75e3 in base::MessageLoop::RunTask(base::PendingTask const&) external/libchrome/base/message_loop/message_loop.cc:494:19
    #12 0x77c9df80b7 in base::MessageLoop::DeferOrRunPendingTask(base::PendingTask) external/libchrome/base/message_loop/message_loop.cc:503:5
    #13 0x77c9df8fb7 in base::MessageLoop::DoWork() external/libchrome/base/message_loop/message_loop.cc:627:13
    #14 0x77c9dfd33b in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) external/libchrome/base/message_loop/message_pump_default.cc:35:31
    #15 0x77c9e4e327 in base::RunLoop::Run() external/libchrome/base/run_loop.cc:35:10
    #16 0x77ca3e97ab in btu_message_loop_run(void*) system/bt/stack/btu/btu_task.cc:98:14
    #17 0x77ca52ad3b in work_queue_read_cb(void*) system/bt/osi/src/thread.cc:251:3
    #18 0x77ca52489b in run_reactor(reactor_t*, int) system/bt/osi/src/reactor.cc:282:11
    #19 0x77ca524413 in reactor_start(reactor_t*) system/bt/osi/src/reactor.cc:125:10
    #20 0x77ca529c6f in run_thread(void*) system/bt/osi/src/thread.cc:221:3
    #21 0x77eb40a31b in __pthread_start(void*) bionic/libc/bionic/pthread_create.cpp:214:18
    #22 0x77eb3c1dff in __start_thread bionic/libc/bionic/clone.cpp:47:16

002(bluetooth) btu message loo identical 2 lines

Address 0x0077c8c0c066 is located in stack of thread T38 (btu message loo)
 at offset 646 in frame

    #0 0x77ca114293 in bta_gattc_process_indicate(unsigned short, unsigned char, tGATT_CL_COMPLETE*) system/bt/bta/gatt/bta_gattc_act.cc:1538:0

002(bluetooth) btu message loo identical 1 line

  This frame has 4 object(s):

    [32, 646) 'notify' (line 1543)
    [784, 790) 'remote_bda' (line 1544) <== Memory access at offset 646 partially underflows this variable
    [816, 817) 'gatt_if' (line 1545) <== Memory access at offset 646 partially underflows this variable
    [832, 833) 'transport' (line 1546) <== Memory access at offset 646 partially underflows this variable

HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext

      (longjmp and C++ exceptions *are* supported)

Thread T38 (btu message loo) created by T37 (bt_workqueue) here:

    #0 0x77e50fd46f in __interceptor_pthread_create _asan_rtl_:3
    #1 0x77ca529727 in thread_new_sized(char const*, unsigned long) system/bt/osi/src/thread.cc:87:3
    #2 0x77ca3e9a73 in btu_task_start_up(void*) system/bt/stack/btu/btu_task.cc:127:26
    #3 0x77ca52ad3b in work_queue_read_cb(void*) system/bt/osi/src/thread.cc:251:3
    #4 0x77ca52489b in run_reactor(reactor_t*, int) system/bt/osi/src/reactor.cc:282:11
    #5 0x77ca524413 in reactor_start(reactor_t*) system/bt/osi/src/reactor.cc:125:10
    #6 0x77ca529c6f in run_thread(void*) system/bt/osi/src/thread.cc:221:3
    #7 0x77eb40a31b in __pthread_start(void*) bionic/libc/bionic/pthread_create.cpp:214:18
    #8 0x77eb3c1dff in __start_thread bionic/libc/bionic/clone.cpp:47:16

002(bluetooth) btu message loo identical 1 line

Thread T37 (bt_workqueue) created by T20 (stack_manager) here:

    #0 0x77e50fd46f in __interceptor_pthread_create _asan_rtl_:3
    #1 0x77ca529727 in thread_new_sized(char const*, unsigned long) system/bt/osi/src/thread.cc:87:3
    #2 0x77ca3e936f in BTU_StartUp() system/bt/stack/btu/btu_init.cc:129:25
    #3 0x77ca2a513b in event_start_up_stack(void*) system/bt/btif/src/stack_manager.cc:146:3
    #4 0x77ca52ad3b in work_queue_read_cb(void*) system/bt/osi/src/thread.cc:251:3
    #5 0x77ca52489b in run_reactor(reactor_t*, int) system/bt/osi/src/reactor.cc:282:11
    #6 0x77ca524413 in reactor_start(reactor_t*) system/bt/osi/src/reactor.cc:125:10
    #7 0x77ca529c6f in run_thread(void*) system/bt/osi/src/thread.cc:221:3
    #8 0x77eb40a31b in __pthread_start(void*) bionic/libc/bionic/pthread_create.cpp:214:18
    #9 0x77eb3c1dff in __start_thread bionic/libc/bionic/clone.cpp:47:16

002(bluetooth) btu message loo identical 1 line

Thread T20 (stack_manager) created by T0 (droid.bluetooth) here:

    #0 0x77e50fd46f in __interceptor_pthread_create _asan_rtl_:3
    #1 0x77ca529727 in thread_new_sized(char const*, unsigned long) system/bt/osi/src/thread.cc:87:3
    #2 0x77ca2a4e7f in ensure_manager_initialized() system/bt/btif/src/stack_manager.cc:238:23
    #3 0x77ca2a4e7f in stack_manager_get_interface() system/bt/btif/src/stack_manager.cc:251:0
    #4 0x77ca1b7927 in init(bt_callbacks_t*) system/bt/btif/src/bluetooth.cc:144:3
    #5 0x77ca9899fb in android::initNative(_JNIEnv*, _jobject*) packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp:663:13
    #6 0x77e1c87703 in art_quick_generic_jni_trampoline /proc/self/cwd/art/runtime/arch/arm64/quick_entrypoints_arm64.S:2329:0

    #6 0x37ab0579318381f  (<unknown module>)

002(bluetooth) btu message loo identical 1 line

SUMMARY: AddressSanitizer: stack-buffer-overflow (/system/lib64/libclang_rt.asan-aarch64-android.so+0x31adf)

Shadow bytes around the buggy address:
  0x001ef91817b0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
  0x001ef91817c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ef91817d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ef91817e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ef91817f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x001ef9181800: 00 00 00 00 00 00 00 00 00 00 00 00[06]f2 f2 f2
  0x001ef9181810: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 06 f2
  0x001ef9181820: f2 f2 01 f2 01 f3 f3 f3 00 00 00 00 00 00 00 00
  0x001ef9181830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ef9181840: f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00
  0x001ef9181850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb

==1410==ABORTING

Bug: 65381426

Change-Id: Ie632f131b622cc323ce68ec7be152caef23c95ec
1 file changed
tree: e15d90e61aa7ba917d4a89f8dc41206ff06747ad
  1. system/
  2. .clang-format
  3. .gitignore
  4. .gn
  5. Android.bp
  6. Android.mk
  7. BUILD.gn
  8. CleanSpec.mk
  9. EventLogTags.logtags
  10. MODULE_LICENSE_APACHE2
  11. NOTICE
  12. OWNERS
  13. PREUPLOAD.cfg
  14. README.md
README.md

Fluoride Bluetooth stack

Building and running on AOSP

Just build AOSP - Fluoride is there by default.

Building and running on Linux

Instructions for Ubuntu, tested on 14.04 with Clang 3.5.0 and 16.10 with Clang 3.8.0

Download source

mkdir ~/fluoride
cd ~/fluoride
git clone https://android.googlesource.com/platform/packages/modules/Bluetooth/system

Install dependencies (require sudo access):

cd ~/fluoride/bt
build/install_deps.sh

Then fetch third party dependencies:

cd ~/fluoride/bt
mkdir third_party
cd third_party
git clone https://github.com/google/googletest.git
git clone https://android.googlesource.com/platform/external/aac
git clone https://android.googlesource.com/platform/external/libchrome
git clone https://android.googlesource.com/platform/external/libldac
git clone https://android.googlesource.com/platform/external/modp_b64
git clone https://android.googlesource.com/platform/external/tinyxml2
git clone https://android.googlesource.com/platform/hardware/libhardware

And third party dependencies of third party dependencies:

cd fluoride/bt/third_party/libchrome/base/third_party
mkdir valgrind
cd valgrind
curl https://chromium.googlesource.com/chromium/src/base/+/master/third_party/valgrind/valgrind.h?format=TEXT | base64 -d > valgrind.h
curl https://chromium.googlesource.com/chromium/src/base/+/master/third_party/valgrind/memcheck.h?format=TEXT | base64 -d > memcheck.h

NOTE: If packages/modules/Bluetooth/system is checked out under AOSP, then create symbolic links instead of downloading sources

cd packages/modules/Bluetooth/system
mkdir third_party
cd third_party
ln -s ../../../external/aac aac
ln -s ../../../external/libchrome libchrome
ln -s ../../../external/libldac libldac
ln -s ../../../external/modp_b64 modp_b64
ln -s ../../../external/tinyxml2 tinyxml2
ln -s ../../../hardware/libhardware libhardware
ln -s ../../../external/googletest googletest

Generate your build files

cd ~/fluoride/bt
gn gen out/Default

Build

cd ~/fluoride/bt
ninja -C out/Default all

This will build all targets (the shared library, executables, tests, etc) and put them in out/Default. To build an individual target, replace "all" with the target of your choice, e.g. ninja -C out/Default net_test_osi.

Run

cd ~/fluoride/bt/out/Default
LD_LIBRARY_PATH=./ ./bluetoothtbd -create-ipc-socket=fluoride

Eclipse IDE Support

  1. Follows the Chromium project Eclipse Setup Instructions until "Optional: Building inside Eclipse" section (don't do that section, we will set it up differently)

  2. Generate Eclipse settings:

cd packages/modules/Bluetooth/system
gn gen --ide=eclipse out/Default
  1. In Eclipse, do File->Import->C/C++->C/C++ Project Settings, choose the XML location under packages/modules/Bluetooth/system/out/Default

  2. Right click on the project. Go to Preferences->C/C++ Build->Builder Settings. Uncheck "Use default build command", but instead using "ninja -C out/Default"

  3. Goto Behaviour tab, change clean command to "-t clean"