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

Reply via email to