Avoid double-free on failure to dump_descriptor() a cached md
This is a fix for 10423, which was introducd in caa0d15c
in 0.2.4.13-alpha.
Spotted by bobnomnom.
This commit is contained in:
parent
59f50c80d4
commit
46b3b6208d
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor bugfixes:
|
||||||
|
- If we fail to dump a previously cached microdescriptor to disk, avoid
|
||||||
|
freeing duplicate data later on. Fix for bug 10423; bugfix on
|
||||||
|
0.2.4.13-alpha. Spotted by "bobnomnom".
|
|
@ -407,6 +407,26 @@ should_rebuild_md_cache(microdesc_cache_t *cache)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark <b>md</b> as having no body, and release any storage previously held
|
||||||
|
* by its body.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
microdesc_wipe_body(microdesc_t *md)
|
||||||
|
{
|
||||||
|
if (!md)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (md->saved_location != SAVED_IN_CACHE)
|
||||||
|
tor_free(md->body);
|
||||||
|
|
||||||
|
md->off = 0;
|
||||||
|
md->saved_location = SAVED_NOWHERE;
|
||||||
|
md->body = NULL;
|
||||||
|
md->bodylen = 0;
|
||||||
|
md->no_save = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** Regenerate the main cache file for <b>cache</b>, clear the journal file,
|
/** Regenerate the main cache file for <b>cache</b>, clear the journal file,
|
||||||
* and update every microdesc_t in the cache with pointers to its new
|
* and update every microdesc_t in the cache with pointers to its new
|
||||||
* location. If <b>force</b> is true, do this unconditionally. If
|
* location. If <b>force</b> is true, do this unconditionally. If
|
||||||
|
@ -455,12 +475,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
|
||||||
|
|
||||||
size = dump_microdescriptor(fd, md, &annotation_len);
|
size = dump_microdescriptor(fd, md, &annotation_len);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
if (md->saved_location != SAVED_IN_CACHE)
|
microdesc_wipe_body(md);
|
||||||
tor_free(md->body);
|
|
||||||
md->saved_location = SAVED_NOWHERE;
|
|
||||||
md->off = 0;
|
|
||||||
md->bodylen = 0;
|
|
||||||
md->no_save = 1;
|
|
||||||
|
|
||||||
/* rewind, in case it was a partial write. */
|
/* rewind, in case it was a partial write. */
|
||||||
tor_fd_setpos(fd, off);
|
tor_fd_setpos(fd, off);
|
||||||
|
@ -497,11 +512,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
|
||||||
HT_FOREACH(mdp, microdesc_map, &cache->map) {
|
HT_FOREACH(mdp, microdesc_map, &cache->map) {
|
||||||
microdesc_t *md = *mdp;
|
microdesc_t *md = *mdp;
|
||||||
if (md->saved_location == SAVED_IN_CACHE) {
|
if (md->saved_location == SAVED_IN_CACHE) {
|
||||||
md->off = 0;
|
microdesc_wipe_body(md);
|
||||||
md->saved_location = SAVED_NOWHERE;
|
|
||||||
md->body = NULL;
|
|
||||||
md->bodylen = 0;
|
|
||||||
md->no_save = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue