aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil/map.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-10-20 16:20:38 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-10-20 16:21:05 +0100
commit5d51907c1a6a4625c1fd78c3e6891bea9e4eb7b4 (patch)
tree26fc42b89387ca06f60e3e502d2268a7ef9fda00 /src/libutil/map.c
parentefb617666724d83cd78ea98a1a34c9e71c9a4dcd (diff)
downloadrspamd-5d51907c1a6a4625c1fd78c3e6891bea9e4eb7b4.tar.gz
rspamd-5d51907c1a6a4625c1fd78c3e6891bea9e4eb7b4.zip
[CritFix] Fix race condition in checking of cached maps
Diffstat (limited to 'src/libutil/map.c')
-rw-r--r--src/libutil/map.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/libutil/map.c b/src/libutil/map.c
index 689f1b0c4..a1539525b 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -318,9 +318,12 @@ static void
rspamd_map_cache_cb (gint fd, short what, gpointer ud)
{
struct rspamd_http_map_cached_cbdata *cache_cbd = ud;
+ struct rspamd_map *map;
- g_atomic_int_set (&cache_cbd->map->cache->available, 0);
+ map = cache_cbd->map;
+ g_atomic_int_set (&map->cache->available, 0);
MAP_RELEASE (cache_cbd->shm, "rspamd_http_map_cached_cbdata");
+ msg_debug_map ("cached data is now expired now for %s", map->name);
event_del (&cache_cbd->timeout);
g_slice_free1 (sizeof (*cache_cbd), cache_cbd);
}
@@ -477,7 +480,8 @@ read_data:
goto err;
}
- msg_info_map ("read map data from %s", cbd->data->host);
+ msg_info_map ("read map data from %s (%z bytes)", cbd->data->host,
+ dlen);
map->read_callback (in, cbd->data_len, &cbd->periodic->cbdata, TRUE);
/*
@@ -602,6 +606,7 @@ rspamd_map_periodic_dtor (struct map_periodic_cbdata *periodic)
if (periodic->locked) {
rspamd_map_schedule_periodic (periodic->map, FALSE, FALSE, FALSE);
g_atomic_int_set (periodic->map->locked, 0);
+ msg_debug_map ("unlocked map");
}
g_slice_free1 (sizeof (*periodic), periodic);
@@ -720,16 +725,21 @@ rspamd_map_read_cached (struct rspamd_map *map,
in = rspamd_shmem_xmap (map->cache->shmem_name, PROT_READ, &len);
if (in == NULL) {
+ msg_err ("cannot map cache from %s: %s", map->cache->shmem_name,
+ strerror (errno));
return FALSE;
}
if (len < map->cache->len) {
+ msg_err ("cannot map cache from %s: bad length %z, %z expected",
+ map->cache->shmem_name,
+ len, map->cache->len);
munmap (in, len);
return FALSE;
}
map->read_callback (in, map->cache->len, &periodic->cbdata, TRUE);
- msg_info_map ("read map data from %s (cached)", host);
+ msg_info_map ("read map data from %s (cached) (%z bytes)", host, len);
munmap (in, len);
return TRUE;
@@ -757,14 +767,19 @@ rspamd_map_common_http_callback (struct rspamd_map *map, struct rspamd_map_backe
periodic->cur_backend = 0;
rspamd_map_periodic_callback (-1, EV_TIMEOUT, periodic);
}
+ else {
+ /* Switch to the next backend */
+ periodic->cur_backend ++;
+ rspamd_map_periodic_callback (-1, EV_TIMEOUT, periodic);
+ }
return;
}
else if (rspamd_map_read_cached (map, periodic, data->host)) {
/* Switch to the next backend */
periodic->cur_backend ++;
- rspamd_map_periodic_callback (-1, EV_TIMEOUT, periodic);
data->last_checked = map->cache->last_checked;
+ rspamd_map_periodic_callback (-1, EV_TIMEOUT, periodic);
return;
}
@@ -835,7 +850,6 @@ rspamd_map_common_http_callback (struct rspamd_map *map, struct rspamd_map_backe
cbd->periodic->errored = TRUE;
}
- /* We don't need own ref as it is now ref counted by DNS handlers */
MAP_RELEASE (cbd, "http_callback_data");
}
@@ -941,6 +955,7 @@ rspamd_map_periodic_callback (gint fd, short what, void *ud)
return;
}
else {
+ msg_debug_map ("locked map");
cbd->locked = TRUE;
}
}
@@ -952,6 +967,8 @@ rspamd_map_periodic_callback (gint fd, short what, void *ud)
if (cbd->locked) {
g_atomic_int_set (cbd->map->locked, 0);
}
+
+ msg_debug_map ("unlocked map");
MAP_RELEASE (cbd, "periodic");
return;
@@ -960,6 +977,8 @@ rspamd_map_periodic_callback (gint fd, short what, void *ud)
/* For each backend we need to check for modifications */
if (cbd->cur_backend >= cbd->map->backends->len) {
/* Last backend */
+ msg_debug_map ("finished map: %d of %d", cbd->cur_backend,
+ cbd->map->backends->len);
MAP_RELEASE (cbd, "periodic");
return;