2 *------------------------------------------------------------------
3 * api_fuzz_test.c - Binary API fuzz hook
5 * Copyright (c) 2020 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
19 #include <vppinfra/format.h>
20 #include <vppinfra/byte_order.h>
21 #include <vppinfra/error.h>
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vlibapi/api.h>
26 static u32 fuzz_seed = 0xdeaddabe;
27 static u16 fuzz_first;
28 static u16 fuzz_cli_first, fuzz_cli_last;
30 extern void (*vl_mem_api_fuzz_hook) (u16, void *);
33 fuzz_hook (u16 id, void *the_msg)
36 * Fuzz (aka screw up) this message? Leave connection establishment
37 * messages alone as well as CLI messages.
39 if ((id > fuzz_first) && !(id >= fuzz_cli_first && id < fuzz_cli_last))
44 mb = (msgbuf_t *) (((u8 *) the_msg) - offsetof (msgbuf_t, data));
46 limit = (u8 *) (mb->data + ntohl (mb->data_len));
49 * Leave the first 14 octets alone, aka msg_id, client_index,
50 * context, sw_if_index
53 start = ((u8 *) the_msg) + 14;
55 for (; start < limit; start++)
56 *start ^= (random_u32 (&fuzz_seed) & 0xFF);
61 default_fuzz_config (void)
63 fuzz_first = vl_msg_api_get_msg_index
64 ((u8 *) "memclnt_keepalive_reply_e8d4e804");
65 fuzz_cli_first = vl_msg_api_get_msg_index ((u8 *) "cli_23bfbfff");
66 fuzz_cli_last = vl_msg_api_get_msg_index
67 ((u8 *) "cli_inband_reply_05879051");
71 test_api_fuzz_command_fn (vlib_main_t * vm,
72 unformat_input_t * input, vlib_cli_command_t * cmd)
76 default_fuzz_config ();
78 if (fuzz_first == 0xFFFF)
80 vlib_cli_output (vm, "Couldn't find 'memclnt_keepalive_reply' ID");
82 (vm, "Manual setting required, use 'show api message table'");
85 if (fuzz_cli_first == 0xFFFF)
87 vlib_cli_output (vm, "Couldn't find 'cli' ID");
89 (vm, "Manual setting required, use 'show api message table'");
92 if (fuzz_cli_last == 0xFFFF)
94 vlib_cli_output (vm, "Couldn't find 'cli_inband_reply' ID");
96 (vm, "Manual setting required, use 'show api message table'");
99 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
101 if (unformat (input, "seed %d", &fuzz_seed))
103 else if (unformat (input, "disable") | unformat (input, "off"))
105 else if (unformat (input, "fuzz-first %d", &tmp))
106 fuzz_first = (u16) tmp;
107 else if (unformat (input, "fuzz-cli-first %d", &tmp))
108 fuzz_cli_first = (u16) tmp;
109 else if (unformat (input, "fuzz-cli-last %d", &tmp))
110 fuzz_cli_last = (u16) tmp;
115 if (fuzz_first == 0xFFFF)
117 vl_mem_api_fuzz_hook = 0;
118 return clib_error_return (0, "fuzz_first is ~0, fuzzing disabled");
120 vl_mem_api_fuzz_hook = fuzz_hook;
122 vlib_cli_output (vm, "Fuzzing enabled: first %d, skip cli range %d - %d",
123 (u32) fuzz_first, (u32) fuzz_cli_first,
124 (u32) fuzz_cli_last);
129 VLIB_CLI_COMMAND (test_api_fuzz, static) = {
130 .path = "test api fuzz",
131 .short_help = "test api fuzz [disable][seed nnn]\n"
132 " [fuzz-first nn][fuzz-cli-first nn][fuzz-cli-last nn]",
133 .function = test_api_fuzz_command_fn,
136 static u8 main_loop_enter_enable_api_fuzz;
138 static clib_error_t *
139 api_fuzz_config (vlib_main_t * vm, unformat_input_t * input)
141 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
143 if (unformat (input, "off")
144 || unformat (input, "disable") || unformat (input, "no"))
145 ; /* ok, no action */
146 else if (unformat (input, "on")
147 || unformat (input, "enable") || unformat (input, "yes"))
148 main_loop_enter_enable_api_fuzz = 1;
150 return clib_error_return (0, "unknown input '%U'",
151 format_unformat_error, input);
156 VLIB_CONFIG_FUNCTION (api_fuzz_config, "api-fuzz");
158 static clib_error_t *
159 api_fuzz_api_init (vlib_main_t * vm)
161 /* Are we supposed to fuzz API messages? */
162 if (main_loop_enter_enable_api_fuzz == 0)
165 default_fuzz_config ();
167 if (fuzz_first == 0xFFFF)
169 return clib_error_return
170 (0, "Couldn't find 'memclnt_keepalive_reply' ID");
172 /* Turn on fuzzing */
173 vl_mem_api_fuzz_hook = fuzz_hook;
177 VLIB_API_INIT_FUNCTION (api_fuzz_api_init);
180 * fd.io coding-style-patch-verification: ON
183 * eval: (c-set-style "gnu")