| From ba52f94929822b1968f05cfbb37985af2e0b83a4 Mon Sep 17 00:00:00 2001 |
| From: Florian Forster <octo@collectd.org> |
| Date: Tue, 13 Sep 2016 10:44:46 +0200 |
| Subject: [PATCH] curl_json plugin: Skip unexpected non-map values. |
| |
| Assume, for example, the config `Key "*/foo"`. This config expects JSON |
| in the form: |
| |
| { |
| "bar": { |
| "foo": 1337 |
| } |
| } |
| |
| If the available JSON is instead: |
| |
| { |
| "error_code": 0, |
| "bar": { |
| "foo": 1337 |
| } |
| } |
| |
| the code will take a look at the zero associated with "error_code" and |
| determine that a map (with key "foo") is expected instead. Previously |
| the code would continue, eventually calling `cj_get_type()` which |
| expects that `key->type` is a valid pointer, resulting in a segmentation |
| fault. |
| |
| This patch does three things to ensure that this segmentation fault does |
| not happen again: |
| |
| 1. `cj_get_type()` checks its argument to make sure it is valid before |
| dereferencing any pointers. |
| 2. In case a non-map is found when a map is expected, the code will |
| return instead of limping on. |
| 3. After calling `cj_cb_inc_array_index()`, which may update the key, |
| make sure that it actually did and that key is valid now. |
| |
| Fixes: #1896 |
| --- |
| src/curl_json.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| diff --git a/src/curl_json.c b/src/curl_json.c |
| index 4188f37..a547ddc 100644 |
| --- a/src/curl_json.c |
| +++ b/src/curl_json.c |
| @@ -143,6 +143,9 @@ static int cj_get_type (cj_key_t *key) |
| { |
| const data_set_t *ds; |
| |
| + if ((key == NULL) || !CJ_IS_KEY (key)) |
| + return -EINVAL; |
| + |
| ds = plugin_get_ds (key->type); |
| if (ds == NULL) |
| { |
| @@ -226,12 +229,15 @@ static int cj_cb_number (void *ctx, |
| buffer[sizeof (buffer) - 1] = 0; |
| |
| if ((key == NULL) || !CJ_IS_KEY (key)) { |
| - if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) |
| + if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) { |
| NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects" |
| " a map.", buffer); |
| + return (CJ_CB_CONTINUE); |
| + } |
| + |
| cj_cb_inc_array_index (ctx, /* update_key = */ 1); |
| key = db->state[db->depth].key; |
| - if (key == NULL) { |
| + if ((key == NULL) || !CJ_IS_KEY (key)) { |
| return (CJ_CB_CONTINUE); |
| } |
| } |