summaryrefslogtreecommitdiff
path: root/agent/cache.c
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:19 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:19 +0900
commitd9787447fe6a57e39113b60305b4ab672b9ba897 (patch)
tree6c925adf6340a1a5ab43d9048ca4b27eae819cd6 /agent/cache.c
parentf77eedfaad1525168ca8593a3eb43ef157cd2891 (diff)
downloadgpg2-d9787447fe6a57e39113b60305b4ab672b9ba897.tar.gz
gpg2-d9787447fe6a57e39113b60305b4ab672b9ba897.tar.bz2
gpg2-d9787447fe6a57e39113b60305b4ab672b9ba897.zip
Imported Upstream version 2.1.19upstream/2.1.19
Diffstat (limited to 'agent/cache.c')
-rw-r--r--agent/cache.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/agent/cache.c b/agent/cache.c
index f58eaea..41e0905 100644
--- a/agent/cache.c
+++ b/agent/cache.c
@@ -475,6 +475,29 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
void
agent_store_cache_hit (const char *key)
{
- xfree (last_stored_cache_key);
- last_stored_cache_key = key? xtrystrdup (key) : NULL;
+ char *new;
+ char *old;
+
+ /* To make sure the update is atomic under the non-preemptive thread
+ * model, we must make sure not to surrender control to a different
+ * thread. Therefore, we avoid calling the allocator during the
+ * update.
+ *
+ * Background: xtrystrdup uses gcry_strdup which may use the secure
+ * memory allocator of Libgcrypt. That allocator takes locks and
+ * since version 1.14 libgpg-error is nPth aware and thus taking a
+ * lock may now lead to thread switch. Note that this only happens
+ * when secure memory is _allocated_ (the standard allocator uses
+ * malloc which is not nPth aware) but not when calling _xfree_
+ * because gcry_free needs to check whether the pointer is in secure
+ * memory and thus needs to take a lock.
+ */
+ new = key ? xtrystrdup (key) : NULL;
+
+ /* Atomic update. */
+ old = last_stored_cache_key;
+ last_stored_cache_key = new;
+ /* Done. */
+
+ xfree (old);
}