summaryrefslogtreecommitdiffstats
path: root/g10/keydb.c
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@g10code.com>2015-12-15 12:21:30 +0100
committerNeal H. Walfield <neal@g10code.com>2015-12-15 12:21:30 +0100
commit2e4e10c1dcd8dfeafec51f44ebf26acfeb770c41 (patch)
treeeb1c054a94fc82708178c618d30e0dc31760697f /g10/keydb.c
parentgpg: Use more descriptive names. (diff)
downloadgnupg2-2e4e10c1dcd8dfeafec51f44ebf26acfeb770c41.tar.xz
gnupg2-2e4e10c1dcd8dfeafec51f44ebf26acfeb770c41.zip
gpg: Improve the keyblock cache's transparency.
* kbx/keybox-search.c (keybox_offset): New function. * g10/keydb.c (struct keyblock_cache): Add fields resource and offset. (keyblock_cache_clear): Reset HD->KEYBLOCK_CACHE.RESOURCE and HD->KEYBLOCK_CACHE.OFFSET. (keydb_search): Don't use the cached result if it comes before the current file position. When caching an entry, also record the position at which it was found. -- Signed-off-by: Neal H. Walfield <neal@g10code.com> GnuPG-bug-id: 2187
Diffstat (limited to 'g10/keydb.c')
-rw-r--r--g10/keydb.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/g10/keydb.c b/g10/keydb.c
index d7c35deac..860187fde 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -81,6 +81,9 @@ struct keyblock_cache {
u32 *sigstatus;
int pk_no;
int uid_no;
+ /* Offset of the record in the keybox. */
+ int resource;
+ off_t offset;
};
@@ -245,6 +248,8 @@ keyblock_cache_clear (struct keydb_handle *hd)
hd->keyblock_cache.sigstatus = NULL;
iobuf_close (hd->keyblock_cache.iobuf);
hd->keyblock_cache.iobuf = NULL;
+ hd->keyblock_cache.resource = -1;
+ hd->keyblock_cache.offset = -1;
}
@@ -1701,7 +1706,13 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
&& (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)
&& hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
- && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20))
+ && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20)
+ /* Make sure the current file position occurs before the cached
+ result to avoid an infinite loop. */
+ && (hd->current < hd->keyblock_cache.resource
+ || (hd->current == hd->keyblock_cache.resource
+ && (keybox_offset (hd->active[hd->current].u.kb)
+ <= hd->keyblock_cache.offset))))
{
/* (DESCINDEX is already set). */
if (DBG_CLOCK)
@@ -1772,6 +1783,12 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
&& hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX)
{
hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
+ hd->keyblock_cache.resource = hd->current;
+ /* The current offset is at the start of the next record. Since
+ a record is at least 1 byte, we just use offset - 1, which is
+ within the record. */
+ hd->keyblock_cache.offset
+ = keybox_offset (hd->active[hd->current].u.kb) - 1;
memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
}