hs_shared_from_unserialized(raii_mmaped_file &&map) -> tl::expected<hs_shared_database, error>
{
auto ptr = map.get_map();
- return tl::expected<hs_shared_database, error>{tl::in_place, std::move(map), (hs_database_t *)ptr};
+ auto db = (hs_database_t *)ptr;
+
+ char *info = nullptr;
+ // Check HS database sanity (see #4409 for details)
+ auto ret = hs_database_info(db, &info);
+
+ if (ret != HS_SUCCESS) {
+ if (info) {
+ g_free (info);
+ }
+ return tl::make_unexpected(
+ error{fmt::format("cannot use database {}: error code: {}", map.get_file().get_name(), ret),
+ ret, error_category::IMPORTANT});
+ }
+
+ msg_debug_hyperscan("database: %s, info: %s", map.get_file().get_name(), info);
+
+ if (info) {
+ g_free (info);
+ }
+
+ return tl::expected<hs_shared_database, error>{tl::in_place, std::move(map), db};
}
static auto
rspamd_snprintf (fp, sizeof (fp), "%s/%*xs.hsmp.tmp", hs_cache_dir,
(gint)rspamd_cryptobox_HASHBYTES / 2, hash);
- if ((fd = rspamd_file_xopen (fp, O_WRONLY | O_CREAT | O_EXCL, 00644, 0)) != -1) {
- if (hs_serialize_database (rspamd_hyperscan_get_database(mp->hs_db), &bytes, &len) == HS_SUCCESS) {
+ if ((fd = rspamd_file_xopen (fp, O_WRONLY | O_CREAT | O_EXCL, 00644, 1)) != -1) {
+ int ret;
+ if ((ret = hs_serialize_database (rspamd_hyperscan_get_database(mp->hs_db), &bytes, &len)) == HS_SUCCESS) {
if (write (fd, bytes, len) == -1) {
msg_warn ("cannot write hyperscan cache to %s: %s",
fp, strerror (errno));
}
}
else {
- msg_warn ("cannot serialize hyperscan cache to %s: %s",
- fp, strerror (errno));
+ msg_warn ("cannot serialize hyperscan cache to %s: error code %d",
+ fp, ret);
unlink (fp);
}
close (fd);
}
+ else {
+ msg_warn ("cannot open a temp file %s to write hyperscan cache: %s", fp, strerror(errno));
+ }
}
#endif
/* Should not happen in the real life */
mp->hs_db = rspamd_hyperscan_from_raw_db(db, NULL);
}
- }
- rspamd_multipattern_try_save_hs (mp, hash);
+ rspamd_multipattern_try_save_hs (mp, hash);
+ }
for (i = 0; i < MAX_SCRATCH; i ++) {
mp->scratch[i] = NULL;