1 From: Justus Winter <justus@g10code.com>
2 Date: Wed, 25 Jan 2017 13:51:57 +0100
3 Subject: agent: Fix double free.
5 * agent/cache.c (agent_store_cache_hit): Make sure the update is
8 Previously, the function freed the last key, and duplicated the new
9 key after doing that. There is a chance, however, that calling the
10 allocator surrenders control to a different thread, causing a double
11 free if a different thread also calls this function.
13 To make sure the update is atomic under the non-preemptive thread
14 model, we must make sure not to surrender control to a different
15 thread. Therefore, we avoid calling the allocator during the
18 Signed-off-by: Justus Winter <justus@g10code.com>
19 (cherry picked from commit e175152ef7515921635bf1e00383e812668d13fc)
21 agent/cache.c | 17 +++++++++++++++--
22 1 file changed, 15 insertions(+), 2 deletions(-)
24 diff --git a/agent/cache.c b/agent/cache.c
25 index f58eaeaaa..248368277 100644
28 @@ -475,6 +475,19 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
30 agent_store_cache_hit (const char *key)
32 - xfree (last_stored_cache_key);
33 - last_stored_cache_key = key? xtrystrdup (key) : NULL;
37 + /* To make sure the update is atomic under the non-preemptive thread
38 + * model, we must make sure not to surrender control to a different
39 + * thread. Therefore, we avoid calling the allocator during the
41 + new = key ? xtrystrdup (key) : NULL;
43 + /* Atomic update. */
44 + old = last_stored_cache_key;
45 + last_stored_cache_key = new;