From 7784140f2bd2d5ae44f2be1507ac25f102006155 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Wed, 29 Apr 2020 17:04:10 -0400 Subject: misc: binary api fuzz test fixes Add a hook to src/vlibapi/api_shared.c to fuzz (screw up) binary API messages, e.g. by xoring random data into them before processing. We specifically exempt client connection messages, and inband debug CLI messages. We step over msg_id, client index, client context, and sw_if_index. Otherwise, "make test" vectors fail too rapidly to learn anything. The goal is to reduce the number of crashes caused to zero. We're fairly close with this patch. Add vl_msg_api_max_length(void *mp), which returns the maximum plausible length for a binary API message. Use it to hardern vl_api_from_api_to_new_vec(...) which takes an additional argument - message pointer - so it can verify that astr->length is sane. If it's not sane, return a u8 *vector of the form "insane astr->length nnnn\0". Verify array lengths in vl_api_dhcp6_send_client_message_t_handler(...) and vl_api_dhcp6_pd_send_client_message_t_handler(...). Add a fairly effective binary API fuzz hook to the unittest plugin, and modify the "make test" framework.py to pass "api-fuzz { on|off }" to enable API fuzzing: "make API_FUZZ=on TEST=xxx test-debug" or similar Type: improvement Signed-off-by: Dave Barach Change-Id: I0157267652a163c01553d5267620f719cc6c3bde --- test/ext/vapi_c_test.c | 6 ++++-- test/framework.py | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/ext/vapi_c_test.c b/test/ext/vapi_c_test.c index a91e4014761..b5075e96c10 100644 --- a/test/ext/vapi_c_test.c +++ b/test/ext/vapi_c_test.c @@ -892,7 +892,8 @@ START_TEST (test_api_strings) ck_assert_int_eq (strlen (str), strlen (cstr)); vec_free (cstr); - vstr = vl_api_from_api_to_new_vec (&dump->payload.name_filter); + vstr = vl_api_from_api_to_new_vec (0 /* not really an API message */ , + &dump->payload.name_filter); ck_assert_ptr_ne (vstr, NULL); /* Assert nul terminator NOT present */ ck_assert_int_eq (vec_len (vstr), strlen (str)); @@ -915,7 +916,8 @@ START_TEST (test_api_strings) ck_assert_int_eq (strlen (str), strlen (cstr)); vec_free (cstr); - vstr = vl_api_from_api_to_new_vec (&dump->payload.name_filter); + vstr = vl_api_from_api_to_new_vec (0 /* not a real api msg */ , + &dump->payload.name_filter); ck_assert_ptr_ne (vstr, NULL); /* Assert nul terminator NOT present */ ck_assert_int_eq (vec_len (vstr), strlen (str)); diff --git a/test/framework.py b/test/framework.py index c73b46c491b..9eea8bb03a5 100644 --- a/test/framework.py +++ b/test/framework.py @@ -387,6 +387,10 @@ class VppTestCase(unittest.TestCase): else: default_variant = "" + api_fuzzing = os.getenv("API_FUZZ") + if api_fuzzing is None: + api_fuzzing = 'off' + cls.vpp_cmdline = [cls.vpp_bin, "unix", "{", "nodaemon", debug_cli, "full-coredump", coredump_size, "runtime-dir", cls.tempdir, "}", @@ -398,6 +402,7 @@ class VppTestCase(unittest.TestCase): "statseg", "{", "socket-name", cls.stats_sock, "}", "socksvr", "{", "socket-name", cls.api_sock, "}", "node { ", default_variant, "}", + "api-fuzz {", api_fuzzing, "}", "plugins", "{", "plugin", "dpdk_plugin.so", "{", "disable", "}", "plugin", "rdma_plugin.so", "{", "disable", -- cgit 1.2.3-korg