[PATCH] Fix incorrect double-checked locking in __nss_database_lookup. [BZ #20483]
Florian Weimer
fweimer@redhat.com
Mon Sep 12 18:55:00 GMT 2016
On 08/18/2016 10:49 PM, Torvald Riegel wrote:
> DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name,
> void **fctp)
> {
> - if (DATABASE_NAME_SYMBOL == NULL
> - && __nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING,
> - DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0)
> + /* Relaxed MO is fine because this is just about whether we have to perform
> + the lookup; we will do another acquire-MO load next before assuming that
> + the lookup has happened. */
> + if ((atomic_load_relaxed (&(DATABASE_NAME_SYMBOL)) == NULL)
> + && (__nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING,
> + DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0))
> return -1;
>
> - *ni = DATABASE_NAME_SYMBOL;
> + /* Acquire MO as required by __nss_database_lookup. */
> + *ni = atomic_load_acquire (&(DATABASE_NAME_SYMBOL));
>
> return __nss_lookup (ni, fct_name, fct2_name, fctp);
> }
I'm not sure if this is the double-checked locking pattern we want to
use for new code. GCC currently cannot merge the two loads (and maybe
it never will do so because it is beneficial to treat the separate loads
as an optimization hint).
I still think we would be better off if we centralize this particular
code in a single function with an interface similar to
__nss_database_lookup. The manual inlining seems unnecessary.
Thanks,
Florian
More information about the Libc-alpha
mailing list