diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-04-15 11:43:53 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-04-24 11:00:28 -0400 |
commit | 655f1c8e011a52910152ba52fc24c6e5b85023b4 (patch) | |
tree | 18ac22f4f248846102a03c6f497acd67cfca00c5 /src | |
parent | 6c86e63029ed1f5d32955f2c3e793942fd19e172 (diff) | |
download | tor-655f1c8e011a52910152ba52fc24c6e5b85023b4.tar.gz tor-655f1c8e011a52910152ba52fc24c6e5b85023b4.zip |
consdiffmgr: function to re-validate stored sha3 digests at startup
Diffstat (limited to 'src')
-rw-r--r-- | src/or/consdiffmgr.c | 57 | ||||
-rw-r--r-- | src/or/consdiffmgr.h | 1 | ||||
-rw-r--r-- | src/test/test_consdiffmgr.c | 3 |
3 files changed, 59 insertions, 2 deletions
diff --git a/src/or/consdiffmgr.c b/src/or/consdiffmgr.c index a9938d2f8b..dce8c8b437 100644 --- a/src/or/consdiffmgr.c +++ b/src/or/consdiffmgr.c @@ -370,8 +370,6 @@ consdiffmgr_cleanup(void) smartlist_free(objects); smartlist_free(consensuses); smartlist_free(diffs); - // XXXX for anything where the sha3 doesn't match -- delete it. But not - // XXXX here. Somewhere else? // Actually remove files, if they're not used. consensus_cache_delete_pending(cdm_cache_get()); @@ -391,6 +389,61 @@ consdiffmgr_configure(const consdiff_cfg_t *cfg) } /** + * Scan the consensus diff manager's cache for any grossly malformed entries, + * and mark them as deletable. Return 0 if no problems were found; 1 + * if problems were found and fixed. + */ +int +consdiffmgr_validate(void) +{ + /* Right now, we only check for entries that have bad sha3 values */ + int problems = 0; + + smartlist_t *objects = smartlist_new(); + consensus_cache_find_all(objects, cdm_cache_get(), + NULL, NULL); + SMARTLIST_FOREACH_BEGIN(objects, consensus_cache_entry_t *, obj) { + const char *lv_sha3 = + consensus_cache_entry_get_value(obj, LABEL_SHA3_DIGEST); + if (lv_sha3 == NULL) + continue; + + uint8_t sha3_expected[DIGEST256_LEN]; + uint8_t sha3_received[DIGEST256_LEN]; + int r = cdm_entry_get_sha3_value(sha3_expected, obj, LABEL_SHA3_DIGEST); + if (r == -1) { + /* digest isn't there; that's allowed */ + continue; + } else if (r == -2) { + /* digest is malformed; that's not allowed */ + problems = 1; + consensus_cache_entry_mark_for_removal(obj); + continue; + } + const uint8_t *body; + size_t bodylen; + consensus_cache_entry_incref(obj); + r = consensus_cache_entry_get_body(obj, &body, &bodylen); + if (r == 0) { + crypto_digest256((char *)sha3_received, (const char *)body, bodylen, + DIGEST_SHA3_256); + } + consensus_cache_entry_decref(obj); + if (r < 0) + continue; + + if (fast_memneq(sha3_received, sha3_expected, DIGEST256_LEN)) { + problems = 1; + consensus_cache_entry_mark_for_removal(obj); + continue; + } + + } SMARTLIST_FOREACH_END(obj); + smartlist_free(objects); + return problems; +} + +/** * Helper: build new diffs of <b>flavor</b> as needed */ static void diff --git a/src/or/consdiffmgr.h b/src/or/consdiffmgr.h index 2b3cee264a..3e89ea2b23 100644 --- a/src/or/consdiffmgr.h +++ b/src/or/consdiffmgr.h @@ -33,6 +33,7 @@ void consdiffmgr_rescan(void); int consdiffmgr_cleanup(void); void consdiffmgr_configure(const consdiff_cfg_t *cfg); void consdiffmgr_free_all(void); +int consdiffmgr_validate(void); #ifdef CONSDIFFMGR_PRIVATE STATIC consensus_cache_t *cdm_cache_get(void); diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c index 4eb9e7afba..5161587873 100644 --- a/src/test/test_consdiffmgr.c +++ b/src/test/test_consdiffmgr.c @@ -556,6 +556,9 @@ test_consdiffmgr_cleanup_old_diffs(void *arg) tt_int_op(0, OP_EQ, consdiffmgr_add_consensus(md_body[3], md_ns[3])); tt_int_op(2, OP_EQ, consdiffmgr_cleanup()); + /* Everything should be valid at this point */ + tt_int_op(0, OP_EQ, consdiffmgr_validate()); + done: for (i = 0; i < N; ++i) { tor_free(md_body[i]); |