bluetooth: fix GATT server DB exhaustion on disable/enable cycles#586
Merged
Conversation
2a22540 to
ed15c8f
Compare
chengkai15
reviewed
May 7, 2026
| manager->services = NULL; | ||
| bt_list_free(manager->pend_ops); | ||
| manager->pend_ops = NULL; | ||
| manager->started = false; |
Contributor
There was a problem hiding this comment.
mind:manager->started = false now executes after bt_sal_gatt_server_disable() rather than before
chengkai15
approved these changes
May 7, 2026
zhongzhijie1
approved these changes
May 8, 2026
ed15c8f to
9633e03
Compare
bug: v/87180 bt_sal_gatt_server_disable() only unregistered callbacks without cleaning up server_db[] and server_svcs[] static arrays. Each disable/enable cycle left stale attributes occupying slots, causing attr_count to eventually reach CONFIG_GATT_SERVER_MAX_ATTRIBUTES. - Add full resource cleanup in bt_sal_gatt_server_disable(): unregister all GATT services from zephyr, free SDP records, release all attribute user_data/uuid memory, and reset server_db/server_svcs/ attr_count/svc_attr_count. - Reorder if_gatts_shutdown() to call disable before freeing the upper-layer service list, ensuring zephyr unregister completes first. Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
9633e03 to
bed5b90
Compare
huangyulong3
approved these changes
May 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix GATT server static DB exhaustion across disable/enable cycles.
bt_sal_gatt_server_disable()previously only unregistered GATT/ATT callbacks without cleaning up theserver_db[]andserver_svcs[]static arrays. Each disable/enable cycle left stale attributes occupying slots, soattr_countkept growing until it reachedCONFIG_GATT_SERVER_MAX_ATTRIBUTESand new service registrations failed.Changes:
bt_sal_gatt_server_disable()now iteratesserver_svcs[]and unregisters every active GATT service from the zephyr stack, deletes the associated SDP records, frees each attribute'suser_data/uuidmemory, and resetsserver_db/server_svcs/attr_count/svc_attr_countto their initial state before unregistering callbacks.if_gatts_shutdown()is reordered to callbt_sal_gatt_server_disable()before freeing the upper-layer service list, ensuring zephyr-side unregistration completes while the static DB is still consistent.Impact
Testing
user_data/uuidlifecycle ingatt_db_add()andremove_from_server_db()— the new free pattern matches existing cleanup semantics, no UAF/double-free introducedbt_gatt_service_unregister()is synchronous in zephyr, so freeing attribute memory after unregistration is safegatts register → disable → enablecycles no longer leave staleserver_dbentries