Public bug reported: [ Impact ]
There is an asymmetry in how BlueZ updates the persistent GATT cache when services change during an active connection. When services are added on the remote GATT server (via a Service Changed indication), the DB Hash stored on disk at /var/lib/bluetooth/<adapter_addr>/cache/<remote_addr> is not updated. However, when services are removed, the on-disk DB Hash is updated correctly. As a result, after a service addition the cached DB Hash remains stale. On the next connection, the GATT client compares the remote device's current DB Hash against the cached value and, finding them equal (due to the missed update), incorrectly skips service re-discovery. This means the client operates on an outdated service list and may fail to access newly added services or behave incorrectly against them. We would like to backport upstream commit 0fd01e98 to resolute, which corrects the update logic so that the on-disk DB Hash is written consistently for both service additions and removals. [ Test Plan ] These steps require two Bluetooth devices: a GATT client (the Ubuntu machine under test) and a GATT server (a device whose services can be dynamically added/removed, e.g. a development board or second Linux machine running BlueZ). Reproducing the bug (add-service case): Connect the GATT client to the GATT server and confirm the connection is established. Record the current cached DB Hash on the client: sudo cat /var/lib/bluetooth/DUT_MAC/cache/TEST_HOST_MAC Note the hash embedded in the 00002b2a attribute line, e.g.: 000e=2803:000f:02:f74347d19eef647d97f0b2f7af502e33:00002b2a-0000-1000-8000-00805f9b34fb While the connection remains active, add a new service on the GATT server. The server should send a Service Changed indication to the client. ( You can see new GATT services getting added in bluetoothctl) Re-read the client cache file. Before the fix, the hash is unchanged (bug confirmed). After the fix, the hash should reflect the new service state. Reproducing the bug (remove-service case, expected to pass both before and after fix): Repeat steps 1–2 above. While connected, remove an existing service on the GATT server. Re-read the client cache file. The hash should be updated in both the unfixed and fixed versions, confirming this path was already correct and remains unaffected. Verifying correct GATT re-discovery after fix: Apply the fix, then perform the add-service test above and confirm the hash updates. Attached test_service.py can be used to add and remove services. Run the script to add, kill to remove. [ Where problems could occur ] If some other software will read the DataBase Hash value from cached files and use the value, they may be affected. Maybe their logics got used to use an unchanged DataBase Hash value when adding new services, which should originally be updated. [ Other Info ] The fix has been merged into the BlueZ mainline. Upstream commit: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=0fd01e98cf94616a5c1c39749314cdd4a1654687 This is a pure backport with no Ubuntu-specific changes required. There is no security implication; this is entirely a functional correctness issue in cache management. ** Affects: bluez (Ubuntu) Importance: Undecided Status: New ** Attachment added: "test_service.py" https://bugs.launchpad.net/bugs/2156411/+attachment/5976782/+files/test_service.py ** Description changed: [ Impact ] There is an asymmetry in how BlueZ updates the persistent GATT cache when services change during an active connection. When services are added on the remote GATT server (via a Service Changed indication), the DB Hash stored on disk at /var/lib/bluetooth/<adapter_addr>/cache/<remote_addr> is not updated. However, when services are removed, the on-disk DB Hash is updated correctly. As a result, after a service addition the cached DB Hash remains stale. On the next connection, the GATT client compares the remote device's current DB Hash against the cached value and, finding them equal (due to the missed update), incorrectly skips service re-discovery. This means the client operates on an outdated service list and may fail to access newly added services or behave incorrectly against them. - The fix backports upstream commit 0fd01e98 which corrects the update - logic so that the on-disk DB Hash is written consistently for both - service additions and removals. + We would like to backport upstream commit 0fd01e98 to resolute, which + corrects the update logic so that the on-disk DB Hash is written + consistently for both service additions and removals. [ Test Plan ] These steps require two Bluetooth devices: a GATT client (the Ubuntu machine under test) and a GATT server (a device whose services can be dynamically added/removed, e.g. a development board or second Linux machine running BlueZ). - Reproducing the bug (add-service case): Connect the GATT client to the GATT server and confirm the connection is established. Record the current cached DB Hash on the client: sudo cat /var/lib/bluetooth/DUT_MAC/cache/TEST_HOST_MAC Note the hash embedded in the 00002b2a attribute line, e.g.: 000e=2803:000f:02:f74347d19eef647d97f0b2f7af502e33:00002b2a-0000-1000-8000-00805f9b34fb While the connection remains active, add a new service on the GATT server. The server should send a Service Changed indication to the client. ( You can see new GATT services getting added in bluetoothctl) Re-read the client cache file. Before the fix, the hash is unchanged (bug confirmed). After the fix, the hash should reflect the new service state. - - Reproducing the bug (remove-service case, expected to pass both before and after fix): + Reproducing the bug (remove-service case, expected to pass both before + and after fix): Repeat steps 1–2 above. While connected, remove an existing service on the GATT server. Re-read the client cache file. The hash should be updated in both the unfixed and fixed versions, confirming this path was already correct and remains unaffected. Verifying correct GATT re-discovery after fix: Apply the fix, then perform the add-service test above and confirm the hash updates. Attached test_service.py can be used to add and remove services. Run the script to add, kill to remove. [ Where problems could occur ] If some other software will read the DataBase Hash value from cached files and use the value, they may be affected. Maybe their logics got used to use an unchanged DataBase Hash value when adding new services, which should originally be updated. [ Other Info ] The fix has been merged into the BlueZ mainline. Upstream commit: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=0fd01e98cf94616a5c1c39749314cdd4a1654687 This is a pure backport with no Ubuntu-specific changes required. There is no security implication; this is entirely a functional correctness issue in cache management. -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2156411 Title: [SRU] GATT cached db hash is not updating when adding services to existing connection To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/2156411/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
