chiark / gitweb /
agent: Fix double free.
authorJustus Winter <justus@g10code.com>
Wed, 25 Jan 2017 12:51:57 +0000 (13:51 +0100)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Mon, 18 Sep 2017 20:41:12 +0000 (21:41 +0100)
* agent/cache.c (agent_store_cache_hit): Make sure the update is
atomic.
--
Previously, the function freed the last key, and duplicated the new
key after doing that.  There is a chance, however, that calling the
allocator surrenders control to a different thread, causing a double
free if a different thread also calls this function.

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.

Signed-off-by: Justus Winter <justus@g10code.com>
(cherry picked from commit e175152ef7515921635bf1e00383e812668d13fc)

Gbp-Pq: Name 0017-agent-Fix-double-free.patch

agent/cache.c

index f58eaeaaaf1a0817dc4e1ef4ece93617bc48892b..24836827781f77a481e4bb750bf7a65bc30665a7 100644 (file)
@@ -475,6 +475,19 @@ 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.  */
+  new = key ? xtrystrdup (key) : NULL;
+
+  /* Atomic update.  */
+  old = last_stored_cache_key;
+  last_stored_cache_key = new;
+  /* Done.  */
+
+  xfree (old);
 }