Type: refactor Change-Id: I5235bf3e9aff58af6ba2c14e8c6529c4fc9ec86c Signed-off-by: Damjan Marion <damarion@cisco.com>
186 lines
5.0 KiB
C
186 lines
5.0 KiB
C
/*
|
|
*------------------------------------------------------------------
|
|
* api_fuzz_test.c - Binary API fuzz hook
|
|
*
|
|
* Copyright (c) 2020 Cisco and/or its affiliates.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*------------------------------------------------------------------
|
|
*/
|
|
#include <vppinfra/format.h>
|
|
#include <vppinfra/byte_order.h>
|
|
#include <vppinfra/error.h>
|
|
#include <vlib/vlib.h>
|
|
#include <vlib/unix/unix.h>
|
|
#include <vlibapi/api.h>
|
|
|
|
static u32 fuzz_seed = 0xdeaddabe;
|
|
static u16 fuzz_first;
|
|
static u16 fuzz_cli_first, fuzz_cli_last;
|
|
|
|
extern void (*vl_mem_api_fuzz_hook) (u16, void *);
|
|
|
|
static void
|
|
fuzz_hook (u16 id, void *the_msg)
|
|
{
|
|
/*
|
|
* Fuzz (aka screw up) this message? Leave connection establishment
|
|
* messages alone as well as CLI messages.
|
|
*/
|
|
if ((id > fuzz_first) && !(id >= fuzz_cli_first && id < fuzz_cli_last))
|
|
{
|
|
msgbuf_t *mb;
|
|
u8 *limit, *start;
|
|
|
|
mb = (msgbuf_t *) (((u8 *) the_msg) - offsetof (msgbuf_t, data));
|
|
|
|
limit = (u8 *) (mb->data + ntohl (mb->data_len));
|
|
|
|
/*
|
|
* Leave the first 14 octets alone, aka msg_id, client_index,
|
|
* context, sw_if_index
|
|
*/
|
|
|
|
start = ((u8 *) the_msg) + 14;
|
|
|
|
for (; start < limit; start++)
|
|
*start ^= (random_u32 (&fuzz_seed) & 0xFF);
|
|
}
|
|
}
|
|
|
|
static void
|
|
default_fuzz_config (void)
|
|
{
|
|
fuzz_first = vl_msg_api_get_msg_index
|
|
((u8 *) "memclnt_keepalive_reply_e8d4e804");
|
|
fuzz_cli_first = vl_msg_api_get_msg_index ((u8 *) "cli_23bfbfff");
|
|
fuzz_cli_last = vl_msg_api_get_msg_index
|
|
((u8 *) "cli_inband_reply_05879051");
|
|
}
|
|
|
|
static clib_error_t *
|
|
test_api_fuzz_command_fn (vlib_main_t * vm,
|
|
unformat_input_t * input, vlib_cli_command_t * cmd)
|
|
{
|
|
u32 tmp;
|
|
|
|
default_fuzz_config ();
|
|
|
|
if (fuzz_first == 0xFFFF)
|
|
{
|
|
vlib_cli_output (vm, "Couldn't find 'memclnt_keepalive_reply' ID");
|
|
vlib_cli_output
|
|
(vm, "Manual setting required, use 'show api message table'");
|
|
}
|
|
|
|
if (fuzz_cli_first == 0xFFFF)
|
|
{
|
|
vlib_cli_output (vm, "Couldn't find 'cli' ID");
|
|
vlib_cli_output
|
|
(vm, "Manual setting required, use 'show api message table'");
|
|
}
|
|
|
|
if (fuzz_cli_last == 0xFFFF)
|
|
{
|
|
vlib_cli_output (vm, "Couldn't find 'cli_inband_reply' ID");
|
|
vlib_cli_output
|
|
(vm, "Manual setting required, use 'show api message table'");
|
|
}
|
|
|
|
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
|
{
|
|
if (unformat (input, "seed %d", &fuzz_seed))
|
|
;
|
|
else if (unformat (input, "disable") | unformat (input, "off"))
|
|
fuzz_first = ~0;
|
|
else if (unformat (input, "fuzz-first %d", &tmp))
|
|
fuzz_first = (u16) tmp;
|
|
else if (unformat (input, "fuzz-cli-first %d", &tmp))
|
|
fuzz_cli_first = (u16) tmp;
|
|
else if (unformat (input, "fuzz-cli-last %d", &tmp))
|
|
fuzz_cli_last = (u16) tmp;
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (fuzz_first == 0xFFFF)
|
|
{
|
|
vl_mem_api_fuzz_hook = 0;
|
|
return clib_error_return (0, "fuzz_first is ~0, fuzzing disabled");
|
|
}
|
|
vl_mem_api_fuzz_hook = fuzz_hook;
|
|
|
|
vlib_cli_output (vm, "Fuzzing enabled: first %d, skip cli range %d - %d",
|
|
(u32) fuzz_first, (u32) fuzz_cli_first,
|
|
(u32) fuzz_cli_last);
|
|
|
|
return 0;
|
|
}
|
|
|
|
VLIB_CLI_COMMAND (test_api_fuzz, static) = {
|
|
.path = "test api fuzz",
|
|
.short_help = "test api fuzz [disable][seed nnn]\n"
|
|
" [fuzz-first nn][fuzz-cli-first nn][fuzz-cli-last nn]",
|
|
.function = test_api_fuzz_command_fn,
|
|
};
|
|
|
|
static u8 main_loop_enter_enable_api_fuzz;
|
|
|
|
static clib_error_t *
|
|
api_fuzz_config (vlib_main_t * vm, unformat_input_t * input)
|
|
{
|
|
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
|
{
|
|
if (unformat (input, "off")
|
|
|| unformat (input, "disable") || unformat (input, "no"))
|
|
; /* ok, no action */
|
|
else if (unformat (input, "on")
|
|
|| unformat (input, "enable") || unformat (input, "yes"))
|
|
main_loop_enter_enable_api_fuzz = 1;
|
|
else
|
|
return clib_error_return (0, "unknown input '%U'",
|
|
format_unformat_error, input);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VLIB_CONFIG_FUNCTION (api_fuzz_config, "api-fuzz");
|
|
|
|
static clib_error_t *
|
|
api_fuzz_api_init (vlib_main_t * vm)
|
|
{
|
|
/* Are we supposed to fuzz API messages? */
|
|
if (main_loop_enter_enable_api_fuzz == 0)
|
|
return 0;
|
|
|
|
default_fuzz_config ();
|
|
|
|
if (fuzz_first == 0xFFFF)
|
|
{
|
|
return clib_error_return
|
|
(0, "Couldn't find 'memclnt_keepalive_reply' ID");
|
|
}
|
|
/* Turn on fuzzing */
|
|
vl_mem_api_fuzz_hook = fuzz_hook;
|
|
return 0;
|
|
}
|
|
|
|
VLIB_API_INIT_FUNCTION (api_fuzz_api_init);
|
|
|
|
/*
|
|
* fd.io coding-style-patch-verification: ON
|
|
*
|
|
* Local Variables:
|
|
* eval: (c-set-style "gnu")
|
|
* End:
|
|
*/
|