From 9b7e8acf792cced80e6775bc5668d9db415cdb46 Mon Sep 17 00:00:00 2001 From: Klement Sekera Date: Mon, 22 Nov 2021 21:26:20 +0100 Subject: api: verify message size on receipt When a message is received, verify that it's sufficiently large to accomodate any VLAs within message. To do that, we need a way to calculate message size including any VLAs. This patch adds such funcionality to vppapigen and necessary C code to use those to validate message size on receipt. Drop messages which are malformed. Type: improvement Signed-off-by: Klement Sekera Change-Id: I2903aa21dee84be6822b064795ba314de46c18f4 --- src/vlibmemory/memclnt_api.c | 28 +++++++++++++++++----------- src/vlibmemory/memory_client.c | 29 +++++++++++++++++++++-------- src/vlibmemory/socket_api.c | 16 ++++++++++------ src/vlibmemory/socket_client.c | 16 ++++++++++------ 4 files changed, 58 insertions(+), 31 deletions(-) (limited to 'src/vlibmemory') diff --git a/src/vlibmemory/memclnt_api.c b/src/vlibmemory/memclnt_api.c index 2b4a2393db3..87bb36a5426 100644 --- a/src/vlibmemory/memclnt_api.c +++ b/src/vlibmemory/memclnt_api.c @@ -58,6 +58,10 @@ #include #undef vl_endianfun +#define vl_calcsizefun +#include +#undef vl_calcsizefun + static void vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t *mp) { @@ -177,6 +181,7 @@ vlib_api_init (void) c->print_json = vl_api_##n##_t_print_json; \ c->tojson = vl_api_##n##_t_tojson; \ c->fromjson = vl_api_##n##_t_fromjson; \ + c->calc_size = vl_api_##n##_t_calc_size; \ c->size = sizeof (vl_api_##n##_t); \ c->traced = 1; /* trace, so these msgs print */ \ c->replay = 0; /* don't replay client create/delete msgs */ \ @@ -505,8 +510,9 @@ api_rx_from_node (vlib_main_t *vm, vlib_node_runtime_t *node, vec_add (long_msg, msg, msg_len); } msg = long_msg; + msg_len = vec_len (long_msg); } - vl_msg_api_handler_no_trace_no_free (msg); + vl_msg_api_handler_no_trace_no_free (msg, msg_len); } /* Free what we've been given. */ @@ -704,20 +710,20 @@ rpc_api_hookup (vlib_main_t *vm) { api_main_t *am = vlibapi_get_main (); #define _(N, n) \ - vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \ - vl_noop_handler, vl_noop_handler, \ - vl_api_##n##_t_print, sizeof (vl_api_##n##_t), \ - 0 /* do not trace */, vl_api_##n##_t_print_json, \ - vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson); + vl_msg_api_set_handlers ( \ + VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, vl_noop_handler, \ + vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0 /* do not trace */, \ + vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ + vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); foreach_rpc_api_msg; #undef _ #define _(N, n) \ - vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \ - vl_noop_handler, vl_noop_handler, \ - vl_api_##n##_t_print, sizeof (vl_api_##n##_t), \ - 1 /* do trace */, vl_api_##n##_t_print_json, \ - vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson); + vl_msg_api_set_handlers ( \ + VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, vl_noop_handler, \ + vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1 /* do trace */, \ + vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ + vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); foreach_plugin_trace_msg; #undef _ diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c index f0b05b70695..54bc8d8f859 100644 --- a/src/vlibmemory/memory_client.c +++ b/src/vlibmemory/memory_client.c @@ -39,6 +39,10 @@ #include #undef vl_endianfun +#define vl_calcsizefun +#include +#undef vl_calcsizefun + /* instantiate all the print functions we know about */ #define vl_print(handle, ...) clib_warning (__VA_ARGS__) #define vl_printfun @@ -240,7 +244,8 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) } rv = clib_net_to_host_u32 (rp->response); - vl_msg_api_handler ((void *) rp); + msgbuf_t *msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data)); + vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len)); break; } return (rv); @@ -289,6 +294,7 @@ vl_client_disconnect (void) svm_queue_t *vl_input_queue; api_main_t *am = vlibapi_get_main (); time_t begin; + msgbuf_t *msgbuf; vl_input_queue = am->vl_input_queue; vl_client_send_disconnect (0 /* wait for reply */ ); @@ -321,10 +327,12 @@ vl_client_disconnect (void) if (ntohs (rp->_vl_msg_id) != VL_API_MEMCLNT_DELETE_REPLY) { clib_warning ("queue drain: %d", ntohs (rp->_vl_msg_id)); - vl_msg_api_handler ((void *) rp); + msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data)); + vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len)); continue; } - vl_msg_api_handler ((void *) rp); + msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data)); + vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len)); break; } @@ -364,11 +372,11 @@ vl_client_install_client_message_handlers (void) { api_main_t *am = vlibapi_get_main (); #define _(N, n) \ - vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \ - noop_handler, vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \ - vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ - vl_api_##n##_t_fromjson); \ + vl_msg_api_set_handlers ( \ + VL_API_##N, #n, vl_api_##n##_t_handler, noop_handler, \ + vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \ + vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ + vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); \ am->api_trace_cfg[VL_API_##N].replay_enable = 0; foreach_api_msg; #undef _ @@ -569,6 +577,11 @@ vl_client_get_first_plugin_msg_id (const char *plugin_name) old_handler = am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY]; am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = (void *) vl_api_get_first_msg_id_reply_t_handler; + if (!am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY]) + { + am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY] = + (uword (*) (void *)) vl_api_get_first_msg_id_reply_t_calc_size; + } /* Ask the data-plane for the message-ID base of the indicated plugin */ mm->first_msg_id_reply_ready = 0; diff --git a/src/vlibmemory/socket_api.c b/src/vlibmemory/socket_api.c index ce834a70aac..3e3f7d5bc04 100644 --- a/src/vlibmemory/socket_api.c +++ b/src/vlibmemory/socket_api.c @@ -45,6 +45,10 @@ #include #undef vl_endianfun +#define vl_calcsizefun +#include +#undef vl_calcsizefun + socket_main_t socket_main; #define SOCK_API_REG_HANDLE_BIT (1<<31) @@ -200,7 +204,7 @@ vl_socket_process_api_msg (vl_api_registration_t * rp, i8 * input_v) u8 *the_msg = (u8 *) (mbp->data); socket_main.current_rp = rp; - vl_msg_api_socket_handler (the_msg); + vl_msg_api_socket_handler (the_msg, ntohl (mbp->data_len)); socket_main.current_rp = 0; } @@ -792,11 +796,11 @@ vl_sock_api_init (vlib_main_t * vm) return 0; #define _(N, n, t) \ - vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \ - vl_noop_handler, vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, sizeof (vl_api_##n##_t), t, \ - vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ - vl_api_##n##_t_fromjson); \ + vl_msg_api_set_handlers ( \ + VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, \ + vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), t, \ + vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ + vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); \ am->api_trace_cfg[VL_API_##N].replay_enable = 0; foreach_vlib_api_msg; #undef _ diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c index 2fb6b8a0c4e..7082d8ba7e0 100644 --- a/src/vlibmemory/socket_client.c +++ b/src/vlibmemory/socket_client.c @@ -36,6 +36,10 @@ #include #undef vl_endianfun +#define vl_calcsizefun +#include +#undef vl_calcsizefun + /* instantiate all the print functions we know about */ #define vl_print(handle, ...) clib_warning (__VA_ARGS__) #define vl_printfun @@ -134,7 +138,7 @@ vl_socket_client_read_internal (socket_client_main_t * scm, int wait) if (vec_len (scm->socket_rx_buffer) >= data_len + sizeof (*mbp)) { - vl_msg_api_socket_handler ((void *) (mbp->data)); + vl_msg_api_socket_handler ((void *) (mbp->data), data_len); if (vec_len (scm->socket_rx_buffer) == data_len + sizeof (*mbp)) _vec_len (scm->socket_rx_buffer) = 0; @@ -433,11 +437,11 @@ vl_sock_client_install_message_handlers (void) { #define _(N, n) \ - vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \ - noop_handler, vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \ - vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ - vl_api_##n##_t_fromjson); + vl_msg_api_set_handlers ( \ + VL_API_##N, #n, vl_api_##n##_t_handler, noop_handler, \ + vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \ + vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ + vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); foreach_sock_client_api_msg; #undef _ } -- cgit 1.2.3-korg