]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Use safe parsers everywhere except configuration 5490/head
authorVsevolod Stakhov <vsevolod@rspamd.com>
Thu, 5 Jun 2025 10:27:20 +0000 (11:27 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Thu, 5 Jun 2025 10:27:20 +0000 (11:27 +0100)
17 files changed:
contrib/libucl/lua_ucl.c
contrib/libucl/ucl.h
src/client/rspamdclient.c
src/controller.c
src/fuzzy_storage.c
src/libmime/lang_detection.c
src/libserver/cfg_rcl.cxx
src/libserver/cfg_utils.cxx
src/libserver/dynamic_cfg.c
src/libserver/roll_history.c
src/libserver/rspamd_control.c
src/libserver/symcache/symcache_impl.cxx
src/libserver/worker_util.c
src/lua/lua_cryptobox.c
src/rspamadm/control.c
src/rspamadm/signtool.c
src/rspamd_proxy.c

index 13c5355cd36f1f1afcac52c18729ce7c1eb42842..13306b9425f24dfa18a6bebb87d9a23b2c8e3b31 100644 (file)
@@ -700,7 +700,7 @@ lua_ucl_parser_init(lua_State *L)
         * files. Macros in the parser are very dangerous and should be used
         * for trusted data only.
         */
-       int flags = UCL_PARSER_NO_FILEVARS|UCL_PARSER_DISABLE_MACRO;
+       int flags = UCL_PARSER_SAFE_FLAGS;
 
        if (lua_gettop(L) >= 1) {
                flags = lua_tonumber(L, 1);
@@ -1097,7 +1097,7 @@ lua_ucl_parser_validate(lua_State *L)
                        }
                }
                else if (lua_type(L, 2) == LUA_TSTRING) {
-                       schema_parser = ucl_parser_new(0);
+                       schema_parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
                        schema_file = luaL_checkstring(L, 2);
 
                        if (!ucl_parser_add_file(schema_parser, schema_file)) {
index b6b9f44c010736f5817561f23f1bc7f673fa676b..8c2ac59a498dec5ebc53fffed1f73e4db6adab85 100644 (file)
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2025 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 /* Copyright (c) 2013-2015, Vsevolod Stakhov
  * All rights reserved.
  *
@@ -159,6 +175,10 @@ typedef enum ucl_parser_flags {
        UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */
 } ucl_parser_flags_t;
 
+#define UCL_PARSER_SAFE_FLAGS (UCL_PARSER_NO_TIME | \
+       UCL_PARSER_NO_IMPLICIT_ARRAYS | \
+       UCL_PARSER_DISABLE_MACRO | \
+       UCL_PARSER_NO_FILEVARS)
 /**
  * String conversion flags, that are used in #ucl_object_fromstring_common function.
  */
index d07b243328e4c4e528d0cf7ab0bd5c4054f7b06e..4d79590c52c7e9a476bf6178ebd77e54106d9ec2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -231,7 +231,7 @@ rspamd_client_finish_handler(struct rspamd_http_connection *conn,
                        }
                }
 
-               parser = ucl_parser_new(0);
+               parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
                if (!ucl_parser_add_chunk_full(parser, start, len,
                                                                           ucl_parser_get_default_priority(parser),
                                                                           UCL_DUPLICATE_APPEND, UCL_PARSE_AUTO)) {
index c64835038b974d8f6d11a5084a04ca92957c7d27..ae2098282cb92bb325d52ebf32c59b48abcdb12a 100644 (file)
@@ -2311,7 +2311,7 @@ rspamd_controller_handle_saveactions(
                return 0;
        }
 
-       parser = ucl_parser_new(0);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
        if (!ucl_parser_add_chunk(parser, msg->body_buf.begin, msg->body_buf.len)) {
                if ((error = ucl_parser_get_error(parser)) != NULL) {
                        msg_err_session("cannot parse input: %s", error);
@@ -2434,7 +2434,7 @@ rspamd_controller_handle_savesymbols(
                return 0;
        }
 
-       parser = ucl_parser_new(0);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
        if (!ucl_parser_add_chunk(parser, msg->body_buf.begin, msg->body_buf.len)) {
                if ((error = ucl_parser_get_error(parser)) != NULL) {
                        msg_err_session("cannot parse input: %s", error);
index 7ed34ef69575b3f5e971f2ef1afe4d4ce07fbb81..58d123712d1244afb86793fea9db7bb1c0619d42 100644 (file)
@@ -342,7 +342,7 @@ ucl_keymap_fin_cb(struct map_cb_data *data, void **target)
                return;
        }
 
-       parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
        if (!ucl_parser_add_chunk(parser, jb->buf->str, jb->buf->len)) {
                msg_err_config("cannot load ucl data: parse error %s",
@@ -1339,7 +1339,8 @@ rspamd_fuzzy_check_callback(struct rspamd_fuzzy_reply *result, void *ud)
                        /* We push shingles merely for commands that modify content to avoid extra work */
                        if (is_shingle && cmd->cmd != FUZZY_CHECK) {
                                lua_newshingle(L, &session->cmd.sgl);
-                       } else {
+                       }
+                       else {
                                lua_pushnil(L);
                        }
 
@@ -1528,7 +1529,8 @@ rspamd_fuzzy_process_command(struct fuzzy_session *session)
                        /* We push shingles merely for commands that modify content to avoid extra work */
                        if (is_shingle && cmd->cmd != FUZZY_CHECK) {
                                lua_newshingle(L, &session->cmd.sgl);
-                       } else {
+                       }
+                       else {
                                lua_pushnil(L);
                        }
 
@@ -2663,7 +2665,7 @@ rspamd_fuzzy_maybe_load_ratelimits(struct rspamd_fuzzy_storage_ctx *ctx)
                                        RSPAMD_DBDIR);
 
        if (access(path, R_OK) != -1) {
-               struct ucl_parser *parser = ucl_parser_new(UCL_PARSER_NO_IMPLICIT_ARRAYS | UCL_PARSER_DISABLE_MACRO);
+               struct ucl_parser *parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
                if (ucl_parser_add_file(parser, path)) {
                        ucl_object_t *obj = ucl_parser_get_object(parser);
                        int loaded = 0;
index 6e180ea6642d52330b205dc2434d59d0aac3a492..07ecff76db48314177a6148eece7a72f0395f391 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -363,7 +363,7 @@ rspamd_language_detector_read_file(struct rspamd_config *cfg,
        double mean = 0, std = 0, delta = 0, delta2 = 0, m2 = 0;
        enum rspamd_language_category cat = RSPAMD_LANGUAGE_MAX;
 
-       parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
        if (!ucl_parser_add_file(parser, path)) {
                msg_warn_config("cannot parse file %s: %s", path,
                                                ucl_parser_get_error(parser));
@@ -825,7 +825,7 @@ rspamd_language_detector_init(struct rspamd_config *cfg)
 
        languages_pattern = g_string_sized_new(PATH_MAX);
        rspamd_printf_gstring(languages_pattern, "%s/stop_words", languages_path);
-       parser = ucl_parser_new(UCL_PARSER_DEFAULT);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
        if (ucl_parser_add_file(parser, languages_pattern->str)) {
                stop_words = ucl_parser_get_object(parser);
index f383669080a9b738a47703ccb97caa2d0dd1680a..b42a40499b35982d4c4d1e2128d134d17c96e967 100644 (file)
@@ -3640,7 +3640,7 @@ rspamd_config_parse_ucl(struct rspamd_config *cfg,
        /* Try to load keyfile if available */
        auto keyfile_name = fmt::format("{}.key", filename);
        rspamd::util::raii_file::open(keyfile_name, O_RDONLY).map([&](const auto &keyfile) {
-               auto *kp_parser = ucl_parser_new(0);
+               auto *kp_parser = ucl_parser_new(UCL_PARSER_DEFAULT);
                if (ucl_parser_add_fd(kp_parser, keyfile.get_fd())) {
                        auto *kp_obj = ucl_parser_get_object(kp_parser);
 
index dfbdc6bee20861b95f0e1b88752c406d2233e307..b430a5fcab56052d7791385027056fa832c551b6 100644 (file)
@@ -1363,7 +1363,7 @@ rspamd_ucl_fin_cb(struct map_cb_data *data, void **target)
        }
 
        /* New data available */
-       auto *parser = ucl_parser_new(0);
+       auto *parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
        if (!ucl_parser_add_chunk(parser, (unsigned char *) cbdata->buf.data(),
                                                          cbdata->buf.size())) {
                msg_err_config("cannot parse map %s: %s",
index 98451707422b8b7e45e942e45771e0c46582a8ca..6d648d7451824d756275f8d75caf863679098208 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -195,7 +195,7 @@ json_config_fin_cb(struct map_cb_data *data, void **target)
                return;
        }
 
-       parser = ucl_parser_new(0);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
        if (!ucl_parser_add_chunk(parser, jb->buf->str, jb->buf->len)) {
                msg_err("cannot load json data: parse error %s",
index 66a53a59718e4a75eba2807065299adae7392f63..d0f145d8f07ef4484a5e18486233a1ae6caf5831 100644 (file)
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -231,7 +231,7 @@ rspamd_roll_history_load(struct roll_history *history, const char *filename)
                return FALSE;
        }
 
-       parser = ucl_parser_new(0);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
        if (!ucl_parser_add_fd(parser, fd)) {
                msg_warn("cannot parse history file %s: %s", filename,
index 1bff2ff12bf6b84bd02aa336135b98d69a6263d7..9e35cb57559eb813f0efeefce72719caa4b8820f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -214,7 +214,7 @@ rspamd_control_write_reply(struct rspamd_control_session *session)
                case RSPAMD_CONTROL_FUZZY_STAT:
                        if (elt->attached_fd != -1) {
                                /* We have some data to parse */
-                               parser = ucl_parser_new(0);
+                               parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
                                ucl_object_insert_key(cur,
                                                                          ucl_object_fromint(
                                                                                  elt->reply.reply.fuzzy_stat.status),
index c0278cfc13ebe24bd9489afb94495c830184c3cc..c1ca2a6ed4f116847223e2b99a484d0830a38e66 100644 (file)
@@ -274,7 +274,7 @@ auto symcache::load_items() -> bool
                return false;
        }
 
-       auto *parser = ucl_parser_new(0);
+       auto *parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
        const auto *p = (const std::uint8_t *) (hdr + 1);
 
        if (!ucl_parser_add_chunk(parser, p, cached_map->get_size() - sizeof(*hdr))) {
index d0ac8d8d3aa9e263d2f8a73f49e5f856838e5b98..685ee9cd2dfa33a2d3ff0c79826971562073a2ba 100644 (file)
@@ -2138,7 +2138,7 @@ rspamd_controller_load_saved_stats(struct rspamd_main *rspamd_main,
                return;
        }
 
-       parser = ucl_parser_new(0);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
        if (!ucl_parser_add_file(parser, cfg->stats_file)) {
                msg_err_config("cannot parse controller stats from %s: %s",
index 721d7125645ce762ef74a0de23ad7844b30d5d4b..2c2254920ed0d68d99e1cc41c03bd6175a9ef89e 100644 (file)
@@ -404,7 +404,7 @@ lua_cryptobox_keypair_load(lua_State *L)
        if (lua_type(L, 1) == LUA_TSTRING) {
                buf = luaL_checklstring(L, 1, &len);
                if (buf != NULL) {
-                       parser = ucl_parser_new(0);
+                       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
                        if (!ucl_parser_add_chunk(parser, buf, len)) {
                                msg_err("cannot open keypair from data: %s",
index 381bdaa7a7430f7466d9929dd4c79d85f3fd872b..cd550c04eec98c5eecb1efeba86d219ce95f5b8e 100644 (file)
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -112,7 +112,7 @@ rspamd_control_finish_handler(struct rspamd_http_connection *conn,
        struct rspamadm_control_cbdata *cbdata = conn->ud;
 
        body = rspamd_http_message_get_body(msg, &body_len);
-       parser = ucl_parser_new(0);
+       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
        if (!body || !ucl_parser_add_chunk(parser, body, body_len)) {
                rspamd_fprintf(stderr, "cannot parse server's reply: %s\n",
index 6d60e6700ed17bbf9ecb17e12757bc9b69d90e25..538767b19b51678122f18fa48ae8b98fc06985f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -573,7 +573,7 @@ rspamadm_signtool(int argc, char **argv, const struct rspamadm_command *cmd)
        else {
                g_assert(keypair_file != NULL);
 
-               parser = ucl_parser_new(0);
+               parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
                if (!ucl_parser_add_file(parser, keypair_file) ||
                        (top = ucl_parser_get_object(parser)) == NULL) {
index 8e69298e63eaa4e13a538de99edc6b8cdd1dc557..04603eb4694f9d005ef498dcb7e70c7bc8078217 100644 (file)
@@ -1012,7 +1012,7 @@ proxy_backend_parse_results(struct rspamd_proxy_session *session,
                RSPAMD_FTOK_ASSIGN(&json_ct, "application/json");
 
                if (ct && rspamd_ftok_casecmp(ct, &json_ct) == 0) {
-                       parser = ucl_parser_new(0);
+                       parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
 
                        if (!ucl_parser_add_chunk(parser, in, inlen)) {
                                char *encoded;