Browse Source

[Fix] Ensure that hyperscan cache written is written properly

tags/1.3.1
Vsevolod Stakhov 7 years ago
parent
commit
62b8b657d9
2 changed files with 30 additions and 3 deletions
  1. 20
    2
      src/hs_helper.c
  2. 10
    1
      src/libserver/re_cache.c

+ 20
- 2
src/hs_helper.c View File

@@ -127,11 +127,11 @@ rspamd_hs_helper_cleanup_dir (struct hs_helper_ctx *ctx, gboolean forced)
}

globbuf.gl_offs = 0;
len = strlen (ctx->hs_dir) + 1 + sizeof ("*.hs");
len = strlen (ctx->hs_dir) + 1 + sizeof ("*.hs.new") + 2;
pattern = g_malloc (len);
rspamd_snprintf (pattern, len, "%s%c%s", ctx->hs_dir, G_DIR_SEPARATOR, "*.hs");

if ((rc = glob (pattern, GLOB_DOOFFS, NULL, &globbuf)) == 0) {
if ((rc = glob (pattern, 0, NULL, &globbuf)) == 0) {
for (i = 0; i < globbuf.gl_pathc; i++) {
if (forced ||
!rspamd_re_cache_is_valid_hyperscan_file (ctx->cfg->re_cache,
@@ -149,6 +149,24 @@ rspamd_hs_helper_cleanup_dir (struct hs_helper_ctx *ctx, gboolean forced)
ret = FALSE;
}

globfree (&globbuf);

memset (&globbuf, 0, sizeof (globbuf));
rspamd_snprintf (pattern, len, "%s%c%s", ctx->hs_dir, G_DIR_SEPARATOR, "*.hs.new");
if ((rc = glob (pattern, 0, NULL, &globbuf)) == 0) {
for (i = 0; i < globbuf.gl_pathc; i++) {
if (unlink (globbuf.gl_pathv[i]) == -1) {
msg_err ("cannot unlink %s: %s", globbuf.gl_pathv[i],
strerror (errno));
ret = FALSE;
}
}
}
else if (rc != GLOB_NOMATCH) {
msg_err ("glob %s failed: %s", pattern, strerror (errno));
ret = FALSE;
}

globfree (&globbuf);
g_free (pattern);


+ 10
- 1
src/libserver/re_cache.c View File

@@ -1318,7 +1318,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
GHashTableIter it, cit;
gpointer k, v;
struct rspamd_re_class *re_class;
gchar path[PATH_MAX];
gchar path[PATH_MAX], npath[PATH_MAX];
hs_database_t *test_db;
gint fd, i, n, *hs_ids = NULL, pcre_flags, re_flags;
guint64 crc;
@@ -1371,6 +1371,8 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
continue;
}

rspamd_snprintf (path, sizeof (path), "%s%c%s.hs.new", cache_dir,
G_DIR_SEPARATOR, re_class->hash);
fd = open (path, O_CREAT|O_TRUNC|O_EXCL|O_WRONLY, 00600);

if (fd == -1) {
@@ -1471,6 +1473,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
g_free (hs_ids);
g_free (hs_pats);
close (fd);
unlink (path);
hs_free_compile_error (hs_errors);

return -1;
@@ -1487,6 +1490,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
re_class->hash);

close (fd);
unlink (path);
g_free (hs_ids);
g_free (hs_flags);
hs_free_database (test_db);
@@ -1514,6 +1518,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
else {
iov[0].iov_base = (void *) rspamd_hs_magic;
}

iov[0].iov_len = RSPAMD_HS_MAGIC_LEN;
iov[1].iov_base = &cache->plt;
iov[1].iov_len = sizeof (cache->plt);
@@ -1535,6 +1540,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
"cannot serialize tree of regexp to %s: %s",
path, strerror (errno));
close (fd);
unlink (path);
g_free (hs_ids);
g_free (hs_flags);
g_free (hs_serialized);
@@ -1566,7 +1572,10 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
g_free (hs_flags);
}

fsync (fd);
close (fd);

/* Now rename temporary file to the new .hs file */
}

return total;

Loading…
Cancel
Save