]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Allow to follow symlinks when safe
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 May 2017 12:59:56 +0000 (13:59 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 May 2017 13:06:40 +0000 (14:06 +0100)
Issue: #1625

16 files changed:
src/client/rspamc.c
src/client/rspamdclient.c
src/fuzzy_storage.c
src/libserver/dkim.c
src/libserver/re_cache.c
src/libutil/map.c
src/libutil/multipattern.c
src/libutil/util.c
src/libutil/util.h
src/lua/lua_cryptobox.c
src/lua/lua_fann.c
src/lua/lua_task.c
src/lua/lua_util.c
src/rspamadm/lua_repl.c
src/rspamadm/signtool.c
src/rspamd_proxy.c

index 21b3fd6a36b9cd2eed889a3f099de4d39045e241..2f09956ca52636fcbc79b8b042acd813f005a8ca 100644 (file)
@@ -340,7 +340,7 @@ rspamc_password_callback (const gchar *option_name,
        if (value != NULL) {
                if (value[0] == '/' || value[0] == '.') {
                        /* Try to open file */
-                       map = rspamd_file_xmap (value, PROT_READ, &sz);
+                       map = rspamd_file_xmap (value, PROT_READ, &sz, 0);
 
                        if (map == NULL) {
                                /* Just use it as a string */
index 6ccdce5f5440ac00c75ae47f7e6a2ad19468f1b7..7ea09618366ce0aff490d8d5515b2c649874af84 100644 (file)
@@ -352,7 +352,8 @@ rspamd_client_command (struct rspamd_client_connection *conn,
                }
                else {
                        if (comp_dictionary) {
-                               dict = rspamd_file_xmap (comp_dictionary, PROT_READ, &dict_len);
+                               dict = rspamd_file_xmap (comp_dictionary, PROT_READ, &dict_len,
+                                               TRUE);
 
                                if (dict == NULL) {
                                        g_set_error (err, RCLIENT_ERROR, errno,
index 90f283b4ab0e6c44d45dbf044852497a361a1031..50bc864bca8988d02e32aa01cb67e942cf0d8340 100644 (file)
@@ -2762,7 +2762,8 @@ start_fuzzy (struct rspamd_worker *worker)
                        if (ctx->collection_id_file) {
                                gint fd;
 
-                               fd = rspamd_file_xopen (ctx->collection_id_file, O_RDONLY, 0);
+                               fd = rspamd_file_xopen (ctx->collection_id_file, O_RDONLY, 0,
+                                               FALSE);
 
                                if (fd == -1) {
                                        if (errno != ENOENT) {
@@ -2862,7 +2863,7 @@ start_fuzzy (struct rspamd_worker *worker)
 
                /* Try to save collection id */
                fd = rspamd_file_xopen (ctx->collection_id_file,
-                               O_WRONLY | O_CREAT | O_TRUNC, 00644);
+                               O_WRONLY | O_CREAT | O_TRUNC, 00644, 0);
 
                if (fd == -1) {
                        msg_err ("cannot open collection id to store in %s: %s",
index eb8c193b5838568161159d833fdcec77888b9561..3a314cac9e1dd0ce1414bc67e8277547469d6f4f 100644 (file)
@@ -1973,7 +1973,7 @@ rspamd_dkim_sign_key_load (const gchar *what, gsize len,
                gchar fpath[PATH_MAX];
 
                rspamd_snprintf (fpath, sizeof (fpath), "%*s", (gint)len, what);
-               map = rspamd_file_xmap (fpath, PROT_READ, &map_len);
+               map = rspamd_file_xmap (fpath, PROT_READ, &map_len, TRUE);
 
                if (map == NULL) {
                        g_set_error (err, dkim_error_quark (), DKIM_SIGERROR_KEYFAIL,
index 8d914c93ab62b39948701c32515a71e12154626e..2302ea8c8996b30d741622f4a5e8ef51f02253be 100644 (file)
@@ -1744,7 +1744,7 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
                        close (fd);
 
                        if (try_load) {
-                               map = rspamd_file_xmap (path, PROT_READ, &len);
+                               map = rspamd_file_xmap (path, PROT_READ, &len, TRUE);
 
                                if (map == NULL) {
                                        msg_err_re_cache ("cannot mmap hyperscan cache file %s: "
index c6a7189a8782dbc6e73a88dceb03407084237375..1855ca5d5fc424de08bdd0d8a348698e2ea7090a 100644 (file)
@@ -180,7 +180,7 @@ rspamd_map_check_file_sig (const char *fname,
        if (bk->trusted_pubkey == NULL) {
                /* Try to load and check pubkey */
                rspamd_snprintf (fpath, sizeof (fpath), "%s.pub", fname);
-               data = rspamd_file_xmap (fpath, PROT_READ, &len);
+               data = rspamd_file_xmap (fpath, PROT_READ, &len, TRUE);
 
                if (data == NULL) {
                        msg_err_map ("can't open pubkey %s: %s", fpath, strerror (errno));
@@ -628,7 +628,7 @@ read_map_file (struct rspamd_map *map, struct file_map_data *data,
                return TRUE;
        }
 
-       bytes = rspamd_file_xmap (data->filename, PROT_READ, &len);
+       bytes = rspamd_file_xmap (data->filename, PROT_READ, &len, TRUE);
 
        if (bytes == NULL) {
                msg_err_map ("can't open map %s: %s", data->filename, strerror (errno));
index 35ef51a7088f9daa94ad5f8d521fc9467746b6c7..508ffcda9b83abe2ff01f2f5fb1f41fd84d0298c 100644 (file)
@@ -470,7 +470,7 @@ rspamd_multipattern_try_load_hs (struct rspamd_multipattern *mp,
        rspamd_snprintf (fp, sizeof (fp), "%s/%*xs.hsmp", hs_cache_dir,
                        (gint)rspamd_cryptobox_HASHBYTES / 2, hash);
 
-       if ((map = rspamd_file_xmap (fp, PROT_READ, &len)) != NULL) {
+       if ((map = rspamd_file_xmap (fp, PROT_READ, &len, TRUE)) != NULL) {
                if (hs_deserialize_database (map, len, &mp->db) == HS_SUCCESS) {
                        munmap (map, len);
                        return TRUE;
@@ -500,7 +500,7 @@ 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)) != -1) {
+       if ((fd = rspamd_file_xopen (fp, O_WRONLY | O_CREAT | O_EXCL, 00644, 0)) != -1) {
                if (hs_serialize_database (mp->db, &bytes, &len) == HS_SUCCESS) {
                        if (write (fd, bytes, len) == -1) {
                                msg_warn ("cannot write hyperscan cache to %s: %s",
index 704d65041836e387149894ee0cac26ecdade1eac..593baf522bc8ad8fb231e3e37e85a31cd720e56f 100644 (file)
@@ -2114,7 +2114,7 @@ rspamd_open_zstd_dictionary (const char *path)
        struct zstd_dictionary *dict;
 
        dict = g_slice_alloc0 (sizeof (*dict));
-       dict->dict = rspamd_file_xmap (path, PROT_READ, &dict->size);
+       dict->dict = rspamd_file_xmap (path, PROT_READ, &dict->size, TRUE);
 
        if (dict->dict == NULL) {
                g_slice_free1 (sizeof (*dict), dict);
@@ -2418,7 +2418,8 @@ event_get_base (struct event *ev)
 #endif
 
 int
-rspamd_file_xopen (const char *fname, int oflags, guint mode)
+rspamd_file_xopen (const char *fname, int oflags, guint mode,
+               gboolean allow_symlink)
 {
        struct stat sb;
        int fd;
@@ -2434,7 +2435,12 @@ rspamd_file_xopen (const char *fname, int oflags, guint mode)
        }
 
 #ifdef HAVE_ONOFOLLOW
-       fd = open (fname, oflags | O_NOFOLLOW, mode);
+       if (!allow_symlink) {
+               fd = open (fname, oflags | O_NOFOLLOW, mode);
+       }
+       else {
+               fd = open (fname, oflags, mode);
+       }
 #else
        fd = open (fname, oflags, mode);
 #endif
@@ -2443,8 +2449,8 @@ rspamd_file_xopen (const char *fname, int oflags, guint mode)
 }
 
 gpointer
-rspamd_file_xmap (const char *fname, guint mode,
-               gsize *size)
+rspamd_file_xmap (const char *fname, guint mode, gsize *size,
+               gboolean allow_symlink)
 {
        gint fd;
        struct stat sb;
@@ -2454,10 +2460,10 @@ rspamd_file_xmap (const char *fname, guint mode,
        g_assert (size != NULL);
 
        if (mode & PROT_WRITE) {
-               fd = rspamd_file_xopen (fname, O_RDWR, 0);
+               fd = rspamd_file_xopen (fname, O_RDWR, 0, allow_symlink);
        }
        else {
-               fd = rspamd_file_xopen (fname, O_RDONLY, 0);
+               fd = rspamd_file_xopen (fname, O_RDONLY, 0, allow_symlink);
        }
 
        if (fd == -1) {
index 605822fee25c6b6480d2fde2a88160d705980eb5..7f6ccc2f631866dee823cc4879e2cfd3140eb1ca 100644 (file)
@@ -479,7 +479,8 @@ struct event_base * event_get_base (struct event *ev);
  * @param mode mode to open
  * @return fd or -1 in case of error
  */
-int rspamd_file_xopen (const char *fname, int oflags, guint mode);
+int rspamd_file_xopen (const char *fname, int oflags, guint mode,
+               gboolean allow_symlink);
 
 /**
  * Map file without following symlinks or special stuff
@@ -488,8 +489,8 @@ int rspamd_file_xopen (const char *fname, int oflags, guint mode);
  * @param size target size (must NOT be NULL)
  * @return pointer to memory (should be freed using munmap) or NULL in case of error
  */
-gpointer rspamd_file_xmap (const char *fname, guint mode,
-               gsize *size);
+gpointer rspamd_file_xmap (const char *fname, guint mode, gsize *size,
+               gboolean allow_symlink);
 
 /**
  * Map named shared memory segment
index 0e28e52bb7656c689150532fa4bbe06ff1e1321b..4a2c62f8b0d0e2737501459403fe0f877a83aa6c 100644 (file)
@@ -190,7 +190,7 @@ lua_cryptobox_pubkey_load (lua_State *L)
 
        filename = luaL_checkstring (L, 1);
        if (filename != NULL) {
-               map = rspamd_file_xmap (filename, PROT_READ, &len);
+               map = rspamd_file_xmap (filename, PROT_READ, &len, TRUE);
 
                if (map == NULL) {
                        msg_err ("cannot open pubkey from file: %s, %s",
@@ -1230,7 +1230,7 @@ lua_cryptobox_verify_file (lua_State *L)
        signature = lua_check_cryptobox_sign (L, 2);
        fname = luaL_checkstring (L, 3);
 
-       map = rspamd_file_xmap (fname, PROT_READ, &len);
+       map = rspamd_file_xmap (fname, PROT_READ, &len, TRUE);
 
        if (map != NULL && pk != NULL && signature != NULL) {
                ret = rspamd_cryptobox_verify (signature->str, map, len,
@@ -1331,7 +1331,7 @@ lua_cryptobox_sign_file (lua_State *L)
                return luaL_error (L, "invalid arguments");
        }
 
-       data = rspamd_file_xmap (filename, PROT_READ, &len);
+       data = rspamd_file_xmap (filename, PROT_READ, &len, TRUE);
 
        if (data == NULL) {
                msg_err ("cannot mmap file %s: %s", filename, strerror (errno));
index 7315de7adb80e645351bbdfe6366b8170e2eb797..b74174fb70dc8bf462dd3dd6e412fe0520e92c94 100644 (file)
@@ -493,7 +493,7 @@ lua_fann_data (lua_State *L)
 
 
                (void)lseek (fd, 0, SEEK_SET);
-               map = rspamd_file_xmap (fpath, PROT_READ, &sz);
+               map = rspamd_file_xmap (fpath, PROT_READ, &sz, TRUE);
                unlink (fpath);
                close (fd);
 
index 4ca66bbb4e393206d878a0c39708174584a58e3d..f58a6068eb11f19532624793749b15e2f2ab16d3 100644 (file)
@@ -4351,7 +4351,7 @@ lua_text_save_in_file (lua_State *L)
                        mode = lua_tonumber (L, 3);
                }
 
-               fd = rspamd_file_xopen (fname, O_CREAT | O_WRONLY | O_EXCL, mode);
+               fd = rspamd_file_xopen (fname, O_CREAT | O_WRONLY | O_EXCL, mode, 0);
 
                if (fd == -1) {
                        lua_pushboolean (L, false);
index 6c6a4201f3c5d089ae45ca4aecc0b5df77f4cd5c..4c674def899c28b48e932acdd1880e35f05df316 100644 (file)
@@ -1632,7 +1632,7 @@ lua_util_create_file (lua_State *L)
                        mode = lua_tonumber (L, 2);
                }
 
-               fd = rspamd_file_xopen (fpath, O_RDWR|O_CREAT|O_EXCL, mode);
+               fd = rspamd_file_xopen (fpath, O_RDWR | O_CREAT | O_EXCL, mode, 0);
 
                if (fd == -1) {
                        lua_pushnil (L);
index 58c803e3e0cc146270e2b0c72a815b2d1a20d242..e3656e8c9166215b6e73145e4af5202f1683c17c 100644 (file)
@@ -352,7 +352,7 @@ rspamadm_lua_message_handler (lua_State *L, gint argc, gchar **argv)
        func_idx = lua_gettop (L);
 
        for (i = 2; argv[i] != NULL; i ++) {
-               map = rspamd_file_xmap (argv[i], PROT_READ, &len);
+               map = rspamd_file_xmap (argv[i], PROT_READ, &len, TRUE);
 
                if (map == NULL) {
                        rspamd_printf ("cannot open %s: %s\n", argv[i], strerror (errno));
index 5965a736b2995230f09b6d82a299b6a311866d6f..1acd46745cdcf7e2199864c2fcbb6ebdab5e0a08 100644 (file)
@@ -133,7 +133,8 @@ rspamadm_edit_file (const gchar *fname)
                map = NULL;
 
                /* Try to touch source anyway */
-               fd_out = rspamd_file_xopen (fname, O_WRONLY|O_CREAT|O_EXCL, 00644);
+               fd_out = rspamd_file_xopen (fname, O_WRONLY | O_CREAT | O_EXCL, 00644,
+                               0);
 
                if (fd_out == -1) {
                        rspamd_fprintf (stderr, "cannot open %s: %s\n", fname,
@@ -144,7 +145,7 @@ rspamadm_edit_file (const gchar *fname)
                close (fd_out);
        }
        else {
-               map = rspamd_file_xmap (fname, PROT_READ, &len);
+               map = rspamd_file_xmap (fname, PROT_READ, &len, TRUE);
 
                if (map == NULL) {
                        rspamd_fprintf (stderr, "cannot open %s: %s\n", fname,
@@ -231,7 +232,7 @@ rspamadm_edit_file (const gchar *fname)
        }
 #endif
 
-       map = rspamd_file_xmap (tmppath, PROT_READ, &len);
+       map = rspamd_file_xmap (tmppath, PROT_READ, &len, TRUE);
 
        if (map == NULL) {
                rspamd_fprintf (stderr, "cannot map %s: %s\n", tmppath,
@@ -241,8 +242,8 @@ rspamadm_edit_file (const gchar *fname)
        }
 
        rspamd_snprintf (run_cmdline, sizeof (run_cmdline), "%s.new", fname);
-       fd_out = rspamd_file_xopen (run_cmdline, O_RDWR|O_CREAT|O_TRUNC,
-                       00600);
+       fd_out = rspamd_file_xopen (run_cmdline, O_RDWR | O_CREAT | O_TRUNC, 00600,
+                       0);
 
        if (fd_out == -1) {
                rspamd_fprintf (stderr, "cannot open new file %s: %s\n", run_cmdline,
@@ -288,7 +289,7 @@ rspamadm_sign_file (const gchar *fname, struct rspamd_cryptobox_keypair *kp)
                fd_input = rspamadm_edit_file (fname);
        }
        else {
-               fd_input = rspamd_file_xopen (fname, O_RDONLY, 0);
+               fd_input = rspamd_file_xopen (fname, O_RDONLY, 0, TRUE);
        }
 
        if (fd_input == -1) {
@@ -300,7 +301,7 @@ rspamadm_sign_file (const gchar *fname, struct rspamd_cryptobox_keypair *kp)
        g_assert (fstat (fd_input, &st) != -1);
 
        rspamd_snprintf (sigpath, sizeof (sigpath), "%s%s", fname, suffix);
-       fd_sig = rspamd_file_xopen (sigpath, O_WRONLY | O_CREAT | O_TRUNC, 00644);
+       fd_sig = rspamd_file_xopen (sigpath, O_WRONLY | O_CREAT | O_TRUNC, 00644, 0);
 
        if (fd_sig == -1) {
                close (fd_input);
@@ -392,7 +393,7 @@ rspamadm_verify_file (const gchar *fname, const guchar *pk)
                suffix = ".sig";
        }
 
-       fd_input = rspamd_file_xopen (fname, O_RDONLY, 0);
+       fd_input = rspamd_file_xopen (fname, O_RDONLY, 0, TRUE);
 
        if (fd_input == -1) {
                rspamd_fprintf (stderr, "cannot open %s: %s\n", fname,
@@ -403,7 +404,7 @@ rspamadm_verify_file (const gchar *fname, const guchar *pk)
        g_assert (fstat (fd_input, &st) != -1);
 
        rspamd_snprintf (sigpath, sizeof (sigpath), "%s%s", fname, suffix);
-       fd_sig = rspamd_file_xopen (sigpath, O_RDONLY, 0);
+       fd_sig = rspamd_file_xopen (sigpath, O_RDONLY, 0, TRUE);
 
        if (fd_sig == -1) {
                close (fd_input);
index 71d3ecaab0f43acb72120db3e775cdc3b4729093..e9858b0ba1d5884c8bc18b57b204b8080f2c2ba8 100644 (file)
@@ -1061,8 +1061,8 @@ proxy_check_file (struct rspamd_http_message *msg,
 
        if (tok) {
                file_str = rspamd_mempool_ftokdup (session->pool, tok);
-               session->map = rspamd_file_xmap (file_str, PROT_READ,
-                               &session->map_len);
+               session->map = rspamd_file_xmap (file_str, PROT_READ, &session->map_len,
+                               TRUE);
 
                if (session->map == NULL) {
                        msg_err_session ("cannot map %s: %s", file_str, strerror (errno));
@@ -1091,7 +1091,7 @@ proxy_check_file (struct rspamd_http_message *msg,
                        if (tok) {
                                file_str = rspamd_mempool_ftokdup (session->pool, tok);
                                session->map = rspamd_file_xmap (file_str, PROT_READ,
-                                               &session->map_len);
+                                               &session->map_len, TRUE);
 
                                if (session->map == NULL) {
                                        msg_err_session ("cannot map %s: %s", file_str, strerror (errno));