]> source.dussan.org Git - rspamd.git/commitdiff
Save platform info as well
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 8 Dec 2015 01:46:04 +0000 (01:46 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 8 Dec 2015 01:46:04 +0000 (01:46 +0000)
src/libserver/re_cache.c

index f41fef648dc37135b5bfb0a53cb964ee66da02af..69597c1d1e5de25e9b2e2d6e99a58a2ab4c3f59b 100644 (file)
@@ -54,7 +54,7 @@
 
 #ifdef WITH_HYPERSCAN
 #define RSPAMD_HS_MAGIC_LEN (sizeof (rspamd_hs_magic))
-static const guchar rspamd_hs_magic[] = {'r', 's', 'h', 's', 'r', 'e', '1'};
+static const guchar rspamd_hs_magic[] = {'r', 's', 'h', 's', 'r', 'e', '1', '0'};
 #endif
 
 struct rspamd_re_class {
@@ -755,7 +755,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
        const gchar **hs_pats = NULL;
        gchar *hs_serialized;
        gsize serialized_len, total = 0;
-       struct iovec iov[5];
+       struct iovec iov[6];
 
        g_hash_table_iter_init (&it, cache->re_classes);
 
@@ -772,7 +772,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
 
                        /* Read number of regexps */
                        g_assert (fd != -1);
-                       lseek (fd, SEEK_SET, RSPAMD_HS_MAGIC_LEN);
+                       lseek (fd, RSPAMD_HS_MAGIC_LEN + sizeof (cache->plt), SEEK_SET);
                        read (fd, &n, sizeof (n));
                        total += n;
                        close (fd);
@@ -880,18 +880,27 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
 
                        hs_free_database (test_db);
 
-                       /* Write N, then all ID's and then the compiled structure */
+                       /*
+                        * Magic - 8 bytes
+                        * Platform - sizeof (platform)
+                        * n - number of regexps
+                        * n * <regexp ids>
+                        * crc - 8 bytes checksum
+                        * <hyperscan blob>
+                        */
+                       crc = XXH64 (hs_serialized, serialized_len, 0xdeadbabe);
                        iov[0].iov_base = (void *)rspamd_hs_magic;
                        iov[0].iov_len = RSPAMD_HS_MAGIC_LEN;
-                       iov[1].iov_base = &n;
-                       iov[1].iov_len = sizeof (n);
-                       crc = XXH64 (hs_serialized, serialized_len, 0xdeadbabe);
-                       iov[2].iov_base = &crc;
-                       iov[2].iov_len = sizeof (crc);
+                       iov[1].iov_base = &cache->plt;
+                       iov[1].iov_len = sizeof (cache->plt);
+                       iov[2].iov_base = &n;
+                       iov[2].iov_len = sizeof (n);
                        iov[3].iov_base = hs_ids;
                        iov[3].iov_len = sizeof (*hs_ids) * n;
-                       iov[4].iov_base = hs_serialized;
-                       iov[4].iov_len = serialized_len;
+                       iov[4].iov_base = &crc;
+                       iov[4].iov_len = sizeof (crc);
+                       iov[5].iov_base = hs_serialized;
+                       iov[5].iov_len = serialized_len;
 
                        if (writev (fd, iov, G_N_ELEMENTS (iov)) == -1) {
                                g_set_error (err,
@@ -936,6 +945,7 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
        struct rspamd_re_class *re_class;
        gsize len;
        const gchar *hash_pos;
+       hs_platform_info_t test_plt;
 
        len = strlen (path);
 
@@ -970,17 +980,35 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
                                return FALSE;
                        }
 
-                       close (fd);
-
                        if (memcmp (magicbuf, rspamd_hs_magic, sizeof (magicbuf)) != 0) {
                                msg_err_re_cache ("cannot open hyperscan cache file %s: "
                                                "bad magic ('%*xs', '%*xs' expected)",
                                                path, (int) RSPAMD_HS_MAGIC_LEN, magicbuf,
                                                (int) RSPAMD_HS_MAGIC_LEN, rspamd_hs_magic);
 
+                               close (fd);
                                return FALSE;
                        }
 
+                       if (read (fd, &test_plt, sizeof (test_plt)) != sizeof (test_plt)) {
+                               msg_err_re_cache ("cannot read hyperscan cache file %s: %s",
+                                               path, strerror (errno));
+                               close (fd);
+                               return FALSE;
+                       }
+
+                       if (memcmp (&test_plt, &cache->plt, sizeof (test_plt)) != 0) {
+                               msg_err_re_cache ("cannot open hyperscan cache file %s: "
+                                               "compiled for a different platform",
+                                               path);
+
+                               close (fd);
+                               return FALSE;
+                       }
+
+                       /* XXX: add crc check */
+                       close (fd);
+
                        return TRUE;
                }
        }