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 --- src/vnet/devices/tap/tapv2_api.c | 2 +- src/vnet/interface_api.c | 2 +- src/vnet/ip/ip_api.c | 5 +++-- src/vnet/ip/punt_api.c | 2 +- src/vnet/lldp/lldp_api.c | 2 +- src/vnet/pg/pg_api.c | 2 +- src/vnet/session/session_api.c | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src/vnet') diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c index 05679377d2a..5aca93ec310 100644 --- a/src/vnet/devices/tap/tapv2_api.c +++ b/src/vnet/devices/tap/tapv2_api.c @@ -134,7 +134,7 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp) /* If a tag was supplied... */ if (vl_api_string_len (&mp->tag)) { - u8 *tag = vl_api_from_api_to_new_vec (&mp->tag); + u8 *tag = vl_api_from_api_to_new_vec (mp, &mp->tag); vnet_set_sw_interface_tag (vnm, tag, ap->sw_if_index); } diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index 5b24a29efc9..846420d7378 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -361,7 +361,7 @@ vl_api_sw_interface_dump_t_handler (vl_api_sw_interface_dump_t * mp) if (mp->name_filter_valid) { - filter = vl_api_from_api_to_new_vec (&mp->name_filter); + filter = vl_api_from_api_to_new_vec (mp, &mp->name_filter); vec_add1 (filter, 0); /* Ensure it's a C string for strcasecmp() */ } diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 3bc46fee59b..d5fa2d32f21 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -1544,13 +1544,14 @@ static void vl_api_ip_punt_redirect_dump_t_handler (vl_api_ip_punt_redirect_dump_t * mp) { vl_api_registration_t *reg; - fib_protocol_t fproto; + fib_protocol_t fproto = FIB_PROTOCOL_IP4; reg = vl_api_client_index_to_registration (mp->client_index); if (!reg) return; - fproto = mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4; + if (mp->is_ipv6 == 1) + fproto = FIB_PROTOCOL_IP6; ip_punt_redirect_walk_ctx_t ctx = { .reg = reg, diff --git a/src/vnet/ip/punt_api.c b/src/vnet/ip/punt_api.c index 2acf8265dc1..3a964b4b7f5 100644 --- a/src/vnet/ip/punt_api.c +++ b/src/vnet/ip/punt_api.c @@ -372,7 +372,7 @@ vl_api_punt_reason_dump_t_handler (vl_api_punt_reason_dump_t * mp) punt_reason_dump_walk_ctx_t ctx = { .reg = reg, .context = mp->context, - .name = vl_api_from_api_to_new_vec (&mp->reason.name), + .name = vl_api_from_api_to_new_vec (mp, &mp->reason.name), }; punt_reason_walk (punt_reason_dump_walk_cb, &ctx); diff --git a/src/vnet/lldp/lldp_api.c b/src/vnet/lldp/lldp_api.c index a6d7fb84bb7..ecb75bcac4b 100644 --- a/src/vnet/lldp/lldp_api.c +++ b/src/vnet/lldp/lldp_api.c @@ -57,7 +57,7 @@ vl_api_lldp_config_t_handler (vl_api_lldp_config_t * mp) int rv = 0; u8 *sys_name = 0; - sys_name = vl_api_from_api_to_new_vec (&mp->system_name); + sys_name = vl_api_from_api_to_new_vec (mp, &mp->system_name); if (lldp_cfg_set (&sys_name, ntohl (mp->tx_hold), ntohl (mp->tx_interval)) != lldp_ok) diff --git a/src/vnet/pg/pg_api.c b/src/vnet/pg/pg_api.c index 18de1e9e8c4..bb58a4f0cec 100644 --- a/src/vnet/pg/pg_api.c +++ b/src/vnet/pg/pg_api.c @@ -122,7 +122,7 @@ vl_api_pg_enable_disable_t_handler (vl_api_pg_enable_disable_t * mp) if (vl_api_string_len (&mp->stream_name) > 0) { - u8 *stream_name = vl_api_from_api_to_new_vec (&mp->stream_name); + u8 *stream_name = vl_api_from_api_to_new_vec (mp, &mp->stream_name); uword *p = hash_get_mem (pg->stream_index_by_name, stream_name); if (p) stream_index = *p; diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index cfeb7bcc349..593f2e18ba0 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -624,7 +624,7 @@ vl_api_app_attach_t_handler (vl_api_app_attach_t * mp) a->options = mp->options; a->session_cb_vft = &session_mq_cb_vft; - a->namespace_id = vl_api_from_api_to_new_vec (&mp->namespace_id); + a->namespace_id = vl_api_from_api_to_new_vec (mp, &mp->namespace_id); if ((rv = vnet_application_attach (a))) { @@ -801,7 +801,7 @@ vl_api_app_namespace_add_del_t_handler (vl_api_app_namespace_add_del_t * mp) goto done; } - ns_id = vl_api_from_api_to_new_vec (&mp->namespace_id); + ns_id = vl_api_from_api_to_new_vec (mp, &mp->namespace_id); vnet_app_namespace_add_del_args_t args = { .ns_id = ns_id, -- cgit 1.2.3-korg