From a9f03564aad7917086d9b3f9cdb98a8613eaaf98 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 30 Nov 2015 10:15:06 +0100 Subject: [PATCH] ceph plugin: Add unit test for parse_keys(). This is used to demonstrate a buffer overflow: when the first part of a key is >63 characters, key_chars_remaining underflows and causes a buffer overflow in the following iteration. Issue: #1350 --- src/Makefile.am | 9 +++++++ src/ceph_test.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ src/daemon/plugin_mock.c | 32 ++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/ceph_test.c diff --git a/src/Makefile.am b/src/Makefile.am index effa3f8c..a9a80891 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1374,3 +1374,12 @@ test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la TESTS = test_utils_mount test_utils_vl_lookup + +if BUILD_PLUGIN_CEPH +test_plugin_ceph_SOURCES = ceph_test.c +test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +test_plugin_ceph_LDADD = daemon/libcommon.la daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS) +check_PROGRAMS += test_plugin_ceph +TESTS += test_plugin_ceph +endif diff --git a/src/ceph_test.c b/src/ceph_test.c new file mode 100644 index 00000000..0eee5bc5 --- /dev/null +++ b/src/ceph_test.c @@ -0,0 +1,64 @@ +/** + * collectd - src/ceph_test.c + * Copyright (C) 2015 Florian octo Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#include "ceph.c" /* sic */ +#include "testing.h" + +DEF_TEST(parse_keys) +{ + struct { + char *str; + char *want; + } cases[] = { + {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied.description.ios_wb.type", "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"}, + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + {"foo:bar", "FooBar"}, + {"foo:bar+", "FooBarPlus"}, + {"foo:bar-", "FooBarMinus"}, + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"}, + {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"}, + {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"}, + {"aa.type", "Aa.type"}, + }; + size_t i; + + for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) + { + char got[DATA_MAX_NAME_LEN]; + + memset (got, 0, sizeof (got)); + + parse_keys (cases[i].str, got); + + CHECK_ZERO (strcmp (got, cases[i].want)); + } + + return 0; +} + +int main (void) +{ + RUN_TEST(parse_keys); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/plugin_mock.c b/src/daemon/plugin_mock.c index 86528809..f3eefd5a 100644 --- a/src/daemon/plugin_mock.c +++ b/src/daemon/plugin_mock.c @@ -26,6 +26,33 @@ #include "plugin.h" +char hostname_g[] = "example.com"; + +int plugin_register_complex_config (const char *type, int (*callback) (oconfig_item_t *)) +{ + return ENOTSUP; +} + +int plugin_register_init (const char *name, plugin_init_cb callback) +{ + return ENOTSUP; +} + +int plugin_register_read (const char *name, int (*callback) (void)) +{ + return ENOTSUP; +} + +int plugin_register_shutdown (const char *name, int (*callback) (void)) +{ + return ENOTSUP; +} + +int plugin_dispatch_values (value_list_t const *vl) +{ + return ENOTSUP; +} + void plugin_log (int level, char const *format, ...) { char buffer[1024]; @@ -38,4 +65,9 @@ void plugin_log (int level, char const *format, ...) printf ("plugin_log (%i, \"%s\");\n", level, buffer); } +cdtime_t plugin_get_interval (void) +{ + return TIME_T_TO_CDTIME_T (10); +} + /* vim: set sw=2 sts=2 et : */ -- 2.11.0