diff options
author | Thomas Haller <thaller@redhat.com> | 2024-01-25 15:16:31 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2024-03-14 09:02:43 +0100 |
commit | 318e1668bf538fae86e951ea7bcaec534123287b (patch) | |
tree | 4571d7bdf8b3a9aed9d75bdd8df28a7a69f102e6 | |
parent | c8a34bcf7e6b528e8b5a29caa95c0f0f35d46e29 (diff) |
glib-aux: fix atomic pattern in nm_ref_string_unref()
It's simply not valid to read the ref-count without an atomic.
The compiler might optimize out the assignment to "r" and read the
_ref_count field multiple times. Thereby, we might at first appear
to be larger than > 1, and later pass 1 to compare-and-exchange.
We need an atomic get here.
Fixes: 19d402782488 ('refstr: inline nm_ref_string_{ref,unref}()')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1847
(cherry picked from commit 5f7a027f59f0dfd7b759c44106a9e3f3da7a8a57)
(cherry picked from commit 0904bab5e2f91b4c836fdccdfc8b6b4d6d478312)
-rw-r--r-- | src/libnm-glib-aux/nm-ref-string.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/libnm-glib-aux/nm-ref-string.h b/src/libnm-glib-aux/nm-ref-string.h index c7cfe87fd0..45313b394e 100644 --- a/src/libnm-glib-aux/nm-ref-string.h +++ b/src/libnm-glib-aux/nm-ref-string.h @@ -83,7 +83,8 @@ nm_ref_string_unref(NMRefString *rstr) /* fast-path: first try to decrement the ref-count without bringing it * to zero. */ - r = rstr->_ref_count; + r = g_atomic_int_get(&rstr->_ref_count); + if (G_LIKELY(r > 1 && g_atomic_int_compare_and_exchange(&rstr->_ref_count, r, r - 1))) return; |