]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Add hyperscan databases sanity check
authorVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 27 Feb 2023 10:56:27 +0000 (10:56 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 27 Feb 2023 10:56:27 +0000 (10:56 +0000)
Issue: #4409

src/libserver/hyperscan_tools.cxx
src/libutil/multipattern.c

index 615aa57aae18a089d88237c61f2d278c45f9bad0..034184cbaaf7d0cbf736e74a1722e5f1f4d12b0b 100644 (file)
@@ -306,7 +306,28 @@ static auto
 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
index 0d6e8b4f4458dc5f3f12a5268e373dec5f05546d..e39374d4200e8778b1a750b1032d199b260185e0 100644 (file)
@@ -429,8 +429,9 @@ rspamd_multipattern_try_save_hs (struct rspamd_multipattern *mp,
        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));
@@ -455,14 +456,17 @@ rspamd_multipattern_try_save_hs (struct rspamd_multipattern *mp,
                        }
                }
                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
 
@@ -515,9 +519,9 @@ rspamd_multipattern_compile (struct rspamd_multipattern *mp, GError **err)
                                        /* 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;