Description:
The initial authentication path obtains a pointer to the globally owned
`initial_auth_plugin_name`. An `authentication_policy` update allocates a new
name, publishes it, and then frees the old name. The handshake can continue to
use its borrowed old pointer after the updater frees it.
The policy mutex protects construction of the policy factors, but the lifetime
of the returned C string is not extended for the consuming handshake.
How to repeat:
1. Build MySQL 8.4 with AddressSanitizer and enable a supported policy such as
`caching_sha2_password`.
2. Pause a new unauthenticated connection immediately after it obtains the
initial authentication plugin-name pointer.
3. In an administrative session, change `@@global.authentication_policy` so
`Policy::update()` replaces `initial_auth_plugin_name` and frees the old
allocation.
4. Resume the handshake and let it compare or otherwise read the old pointer.
The checked lifetime reduction performs the same borrow/publish/free/use
ordering. Its control prints `21`; the trigger aborts in `strcmp` with:
```text
ERROR: AddressSanitizer: heap-use-after-free
READ of size 1
#0 ... __interceptor_strcmp
```
Actual result
The source-level lifetime sequence produces a reproducible heap-use-after-free.
A bounded official 8.4.11 stress run interleaved 240 policy changes and
authentication operations; all operations succeeded and the server remained
healthy, so that non-deterministic run did not hit the race.
Expected result
Every handshake should own or retain an immutable plugin-name value for its
entire use, independent of concurrent policy changes.