From 5ee2167bab92e2d77dd17b78bb000421ab6845ad Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Mon, 1 Dec 2025 12:16:02 +0100 Subject: [PATCH] [nrf fromtree] bluetooth: host: Fix stale RPA usage after invalidation Add !BT_ADV_RPA_VALID check to force RPA regeneration when re-enabling an advertising set after RPA rotation occurred while disabled. The BT_ADV_RANDOM_ADDR_UPDATED flag was added to prevent unnecessary address regeneration (RPA/NRPA) between bt_le_ext_adv_param_set() and bt_le_ext_adv_start() calls. However, this revealed an issue: When RPA rotation (le_force_rpa_timeout) occurs while an advertiser is disabled, BT_ADV_RPA_VALID is cleared but the RPA is not regenerated. On subsequent bt_le_ext_adv_start() without a new param_set() call: - BT_ADV_RANDOM_ADDR_UPDATED is already cleared (from previous start) - Without BT_PER_ADV_ENABLED, no regeneration occurs - Stale RPA is used, violating privacy requirements Add !BT_ADV_RPA_VALID check for both connectable and non-connectable advertisers to ensure fresh RPA generation when the previous RPA was invalidated while the advertiser was disabled. Fixes regression introduced in #98117. Signed-off-by: Pavel Vasilyev (cherry picked from commit 6da559f56544aa2ed1c93071ffad203a523d432c) (cherry picked from commit 16d748b0c1da1df237c6e36e721033468a4d0303) --- subsys/bluetooth/host/adv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 3a17a7192535..4c8ed649fa91 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1566,13 +1566,16 @@ int bt_le_ext_adv_start(struct bt_le_ext_adv *adv, if (IS_ENABLED(CONFIG_BT_PRIVACY) && !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) && (!atomic_test_and_clear_bit(adv->flags, BT_ADV_RANDOM_ADDR_UPDATED) || - atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED))) { + atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED) || + !atomic_test_bit(adv->flags, BT_ADV_RPA_VALID))) { bt_id_set_adv_private_addr(adv); } } else { if (!atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) && (!atomic_test_and_clear_bit(adv->flags, BT_ADV_RANDOM_ADDR_UPDATED) || - atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED))) { + atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED) || + (IS_ENABLED(CONFIG_BT_PRIVACY) && + !atomic_test_bit(adv->flags, BT_ADV_RPA_VALID)))) { bt_id_set_adv_private_addr(adv); } }