The Hearing Access Service (HAS) GATT server in subsys/bluetooth/audio/has.c installs a connection-callback set unconditionally via BTCONNCBDEFINE, so securitychanged() runs for every connection that establishes security even before the application has called bthasregister(). The service attribute pointers hearingaidfeaturesattr, presetcontrolpointattr, and activepresetindexattr remain NULL until bthasregister() resolves them and sets has.registered.
With CONFIGBTSETTINGS, settingssetcb() restores each bonded client's persisted context at boot and unconditionally sets context->flags to BONDEDCLIENTINITFLAGS (non-zero). When a previously bonded peer reconnects and re-establishes security during the startup window before bthasregister() has been called, securitychanged() sees the non-zero flags and schedules notifyworkhandler, which calls btgattissubscribed() with a still-NULL attribute pointer. That triggers an assertion (ASSERT(attr, ...) in btgattissubscribed()), or a NULL dereference of attr->uuid when assertions are compiled out.
The result is a remotely triggerable (Bluetooth, adjacent) crash of the HAS peripheral. Exploitation requires the peer to have previously bonded with the device and to reconnect within the boot-time race window before the application registers the service; a peer that reconnects persistently can prolong the outage. Impact is denial of service only, with no memory corruption or information disclosure.
The fix adds an early if (!has.registered) { return; } guard in securitychanged(), so no notification work is scheduled until the GATT service is registered and its attribute pointers are valid.