]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Fix usage of unsafe ucl iterators
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 10 Jan 2017 12:36:12 +0000 (12:36 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 10 Jan 2017 12:36:12 +0000 (12:36 +0000)
src/controller.c
src/fuzzy_storage.c
src/libserver/cfg_rcl.c
src/libserver/cfg_utils.c
src/libserver/dynamic_cfg.c
src/libutil/map.c

index 9733368a2ed13240a9d5159a7270c8daf52e580f..8949da73307d0cffe69c12814943a4b2f5372d04 100644 (file)
@@ -2001,8 +2001,10 @@ rspamd_controller_handle_saveactions (
                return 0;
        }
 
+       it = ucl_object_iterate_new (obj);
+
        for (i = 0; i < 3; i++) {
-               cur = ucl_object_iterate (obj, &it, TRUE);
+               cur = ucl_object_iterate_safe (it, TRUE);
                if (cur == NULL) {
                        break;
                }
@@ -2029,6 +2031,8 @@ rspamd_controller_handle_saveactions (
                }
        }
 
+       ucl_object_iterate_free (it);
+
        if (dump_dynamic_config (ctx->cfg)) {
                msg_info_session ("<%s> modified %d actions",
                        rspamd_inet_address_to_string (session->from_addr),
@@ -2111,11 +2115,15 @@ rspamd_controller_handle_savesymbols (
                return 0;
        }
 
-       while ((cur = ucl_object_iterate (obj, &iter, true))) {
+       iter = ucl_object_iterate_new (obj);
+
+       while ((cur = ucl_object_iterate_safe (iter, true))) {
                if (cur->type != UCL_OBJECT) {
                        msg_err_session ("json array data error");
                        rspamd_controller_send_error (conn_ent, 400, "Cannot parse input");
                        ucl_object_unref (obj);
+                       ucl_object_iterate_free (iter);
+
                        return 0;
                }
 
@@ -2132,6 +2140,8 @@ rspamd_controller_handle_savesymbols (
                                rspamd_controller_send_error (conn_ent, 506,
                                        "Add symbol failed");
                                ucl_object_unref (obj);
+                               ucl_object_iterate_free (iter);
+
                                return 0;
                        }
                        added ++;
@@ -2144,6 +2154,8 @@ rspamd_controller_handle_savesymbols (
                }
        }
 
+       ucl_object_iterate_free (iter);
+
        if (added > 0) {
                if (ctx->cfg->dynamic_conf) {
                        if (dump_dynamic_config (ctx->cfg)) {
index e0a31a9a48ad5ebe769880f1c18e54394ccbb6f5..a1eb8099783e112c215f36eb12ed4ae96a887a44 100644 (file)
@@ -1985,7 +1985,7 @@ fuzzy_parse_keypair (rspamd_mempool_t *pool,
        else if (ucl_object_type (obj) == UCL_ARRAY) {
                while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
                        if (!fuzzy_parse_keypair (pool, cur, pd, section, err)) {
-                               return FALSE;
+                               msg_err_pool ("cannot parse keypair");
                        }
                }
        }
index 8655ee8de7a5d65b6c1168432464301ab6e3c81f..9d1698c22012fd757de1bb5498278c5abecc2b83 100644 (file)
@@ -420,14 +420,15 @@ rspamd_rcl_actions_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
        struct metric_actions_cbdata *cbdata = ud;
        gint action_value;
        const ucl_object_t *cur;
-       ucl_object_iter_t it = NULL;
+       ucl_object_iter_t it;
        struct rspamd_metric *metric;
        struct rspamd_config *cfg;
 
        metric = cbdata->metric;
        cfg = cbdata->cfg;
+       it = ucl_object_iterate_new (obj);
 
-       while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
+       while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                if (!rspamd_action_from_str (ucl_object_key (cur), &action_value) ||
                                !ucl_object_todouble_safe (cur, &action_score)) {
                        g_set_error (err,
@@ -435,6 +436,8 @@ rspamd_rcl_actions_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                                        EINVAL,
                                        "invalid action definition: '%s'",
                                        ucl_object_key (cur));
+                       ucl_object_iterate_free (it);
+
                        return FALSE;
                }
                else {
@@ -444,6 +447,8 @@ rspamd_rcl_actions_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                }
        }
 
+       ucl_object_iterate_free (it);
+
        return TRUE;
 }
 
@@ -604,6 +609,7 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
        /* This name is more logical */
        if (val != NULL) {
                it = ucl_object_iterate_new (val);
+
                while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                        if (!ucl_object_tostring_safe (cur, &worker_bind)) {
                                continue;
@@ -618,6 +624,7 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                                return FALSE;
                        }
                }
+
                ucl_object_iterate_free (it);
        }
 
@@ -632,8 +639,9 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
        wparser = g_hash_table_lookup (cfg->wrk_parsers, &qtype);
 
        if (wparser != NULL && obj->type == UCL_OBJECT) {
-               it = NULL;
-               while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
+               it = ucl_object_iterate_new (obj);
+
+               while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                        srch.name = ucl_object_key (cur);
                        srch.ptr = wrk->ctx; /* XXX: is it valid? */
                        whandler = g_hash_table_lookup (wparser->parsers, &srch);
@@ -646,6 +654,8 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                                                        &whandler->parser,
                                                        section,
                                                        err)) {
+
+                                               ucl_object_iterate_free (it);
                                                return FALSE;
                                        }
 
@@ -655,6 +665,9 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                                }
                        }
                }
+
+               ucl_object_iterate_free (it);
+
                if (wparser->def_obj_parser != NULL) {
                        robj = ucl_object_ref (obj);
 
@@ -1244,8 +1257,11 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool,
                        ccf->name = ccf->classifier;
                }
 
-               while ((val = ucl_object_iterate (obj, &it, true)) != NULL && res) {
+               it = ucl_object_iterate_new (obj);
+
+               while ((val = ucl_object_iterate_safe (it, true)) != NULL && res) {
                        st_key = ucl_object_key (val);
+
                        if (st_key != NULL) {
                                if (g_ascii_strcasecmp (st_key, "statfile") == 0) {
                                        LL_FOREACH (val, cur) {
@@ -1255,6 +1271,8 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool,
                                                                cur, cfg->cfg_pool, err);
 
                                                if (!res) {
+                                                       ucl_object_iterate_free (it);
+
                                                        return FALSE;
                                                }
                                        }
@@ -1282,6 +1300,8 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool,
                                }
                        }
                }
+
+               ucl_object_iterate_free (it);
        }
        else {
                msg_err_config ("fatal configuration error, cannot parse statfile definition");
@@ -1493,13 +1513,18 @@ rspamd_rcl_composites_handler (rspamd_mempool_t *pool,
        const ucl_object_t *cur;
        gboolean success = TRUE;
 
-       while ((cur = ucl_iterate_object (obj, &it, true))) {
-               success = rspamd_rcl_composite_handler(pool, cur, ucl_object_key(cur), ud, section, err);
+       it = ucl_object_iterate_new (obj);
+
+       while ((cur = ucl_object_iterate_safe (it, true))) {
+               success = rspamd_rcl_composite_handler(pool, cur,
+                               ucl_object_key(cur), ud, section, err);
                if (!success) {
                        break;
                }
        }
 
+       ucl_object_iterate_free (it);
+
        return success;
 }
 
@@ -2487,15 +2512,17 @@ rspamd_rcl_process_section (struct rspamd_config *cfg,
        g_assert (obj != NULL);
        g_assert (sec->handler != NULL);
 
-       it = NULL;
-
        if (sec->key_attr != NULL) {
-               while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
+               it = ucl_object_iterate_new (obj);
+
+               while ((cur = ucl_object_iterate_full (it, UCL_ITERATE_EXPLICIT)) != NULL) {
                        if (ucl_object_type (cur) != UCL_OBJECT) {
                                is_nested = FALSE;
                                break;
                        }
                }
+
+               ucl_object_iterate_free (it);
        }
        else {
                is_nested = FALSE;
@@ -2503,14 +2530,18 @@ rspamd_rcl_process_section (struct rspamd_config *cfg,
 
        if (is_nested) {
                /* Just reiterate on all subobjects */
-               it = NULL;
+               it = ucl_object_iterate_new (obj);
 
-               while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
+               while ((cur = ucl_object_iterate_full (it, UCL_ITERATE_EXPLICIT)) != NULL) {
                        if (!sec->handler (pool, cur, ucl_object_key (cur), ptr, sec, err)) {
+                               ucl_object_iterate_free (it);
+
                                return FALSE;
                        }
                }
 
+               ucl_object_iterate_free (it);
+
                return TRUE;
        }
        else {
@@ -2521,8 +2552,10 @@ rspamd_rcl_process_section (struct rspamd_config *cfg,
                        if (cur == NULL) {
                                if (sec->default_key == NULL) {
                                        g_set_error (err, CFG_RCL_ERROR, EINVAL, "required attribute "
-                                                       "'%s' is missing for section '%s'", sec->key_attr,
-                                                       sec->name);
+                                                       "'%s' is missing for section '%s', current key: %s",
+                                                       sec->key_attr,
+                                                       sec->name,
+                                                       ucl_object_emit (obj, UCL_EMIT_CONFIG));
                                        return FALSE;
                                }
                                else {
@@ -3054,12 +3087,16 @@ rspamd_rcl_parse_struct_string_list (rspamd_mempool_t *pool,
                                        EINVAL,
                                        "cannot convert an object or array to string: %s",
                                        ucl_object_key (obj));
+                       ucl_object_iterate_free (iter);
+
                        return FALSE;
                }
 
                rspamd_rcl_insert_string_list_item (target, pool, val, is_hash);
        }
 
+       ucl_object_iterate_free (iter);
+
        if (*target == NULL) {
                g_set_error (err,
                                CFG_RCL_ERROR,
index 8ee284212afdb0e6f647754bcc01446cff4b125e..606ef3cf79afe575d448994fbc9e4c25d322c9fc 100644 (file)
@@ -1698,7 +1698,9 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg,
                        break;
                case UCL_ARRAY:
                        /* List of IP addresses */
-                       while ((cur = ucl_iterate_object (cur_elt, &it, true)) != NULL) {
+                       it = ucl_object_iterate_new (cur_elt);
+
+                       while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                                str = ucl_object_tostring (cur);
 
                                if (str == NULL || !radix_add_generic_iplist (str, target, TRUE)) {
@@ -1710,9 +1712,13 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg,
                                                radix_destroy_compressed (*target);
                                        }
 
+                                       ucl_object_iterate_free (it);
+
                                        return FALSE;
                                }
                        }
+
+                       ucl_object_iterate_free (it);
                        break;
                default:
                        g_set_error (err, g_quark_from_static_string ("rspamd-config"),
index b74b0a8f9bdfcde16697e495c1e0fed34450f83a..6e319ed36d56282826ad54d3e951b703a7f3c4af 100644 (file)
@@ -346,16 +346,22 @@ dynamic_metric_find_elt (const ucl_object_t *arr, const gchar *name)
        ucl_object_iter_t it = NULL;
        const ucl_object_t *cur, *n;
 
-       while ((cur = ucl_object_iterate (arr, &it, true)) != NULL) {
+       it = ucl_object_iterate_new (arr);
+
+       while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                if (cur->type == UCL_OBJECT) {
                        n = ucl_object_lookup (cur, "name");
                        if (n && n->type == UCL_STRING &&
                                strcmp (name, ucl_object_tostring (n)) == 0) {
+                               ucl_object_iterate_free (it);
+
                                return (ucl_object_t *)ucl_object_lookup (cur, "value");
                        }
                }
        }
 
+       ucl_object_iterate_free (it);
+
        return NULL;
 }
 
@@ -365,16 +371,22 @@ dynamic_metric_find_metric (const ucl_object_t *arr, const gchar *metric)
        ucl_object_iter_t it = NULL;
        const ucl_object_t *cur, *n;
 
-       while ((cur = ucl_object_iterate (arr, &it, true)) != NULL) {
+       it = ucl_object_iterate_new (arr);
+
+       while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                if (cur->type == UCL_OBJECT) {
                        n = ucl_object_lookup (cur, "metric");
                        if (n && n->type == UCL_STRING &&
                                strcmp (metric, ucl_object_tostring (n)) == 0) {
+                               ucl_object_iterate_free (it);
+
                                return (ucl_object_t *)cur;
                        }
                }
        }
 
+       ucl_object_iterate_free (it);
+
        return NULL;
 }
 
index 3a7cdc0324234062592cbc41fdc18a8cba1c47aa..361abcee4ab2a90a20c6a92f0d434847c7e5ee3b 100644 (file)
@@ -1628,7 +1628,9 @@ rspamd_map_add_from_ucl (struct rspamd_config *cfg,
 
                if (ucl_object_type (elt) == UCL_ARRAY) {
                        /* Add array of maps as multiple backends */
-                       while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) {
+                       it = ucl_object_iterate_new (elt);
+
+                       while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
                                if (ucl_object_type (cur) == UCL_STRING) {
                                        bk = rspamd_map_parse_backend (cfg, ucl_object_tostring (cur));
 
@@ -1643,10 +1645,13 @@ rspamd_map_add_from_ucl (struct rspamd_config *cfg,
                                else {
                                        msg_err_config ("bad map element type: %s",
                                                        ucl_object_type_to_string (ucl_object_type (cur)));
+                                       ucl_object_iterate_free (it);
                                        goto err;
                                }
                        }
 
+                       ucl_object_iterate_free (it);
+
                        if (map->backends->len == 0) {
                                msg_err_config ("map has no urls to be loaded: empty object list");
                                goto err;