diff options
Diffstat (limited to 'src/vlibapi')
-rw-r--r-- | src/vlibapi/api.h | 1 | ||||
-rw-r--r-- | src/vlibapi/api_shared.c | 27 | ||||
-rw-r--r-- | src/vlibapi/api_types.h | 2 |
3 files changed, 28 insertions, 2 deletions
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h index 3d5c8698f73..431155c5e09 100644 --- a/src/vlibapi/api.h +++ b/src/vlibapi/api.h @@ -109,6 +109,7 @@ void vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, void *the_msg, vlib_main_t * vm, vlib_node_runtime_t * node, u8 is_private); +u32 vl_msg_api_max_length (void *mp); vl_api_trace_t *vl_msg_api_trace_get (api_main_t * am, vl_api_trace_which_t which); void vl_msg_api_add_msg_name_crc (api_main_t * am, const char *string, diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c index 28e9f481650..fbaa9c9e013 100644 --- a/src/vlibapi/api_shared.c +++ b/src/vlibapi/api_shared.c @@ -533,6 +533,8 @@ msg_handler_internal (api_main_t * am, } } +void (*vl_msg_api_fuzz_hook) (u16, void *); + /* This is only to be called from a vlib/vnet app */ void vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, @@ -600,6 +602,10 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, am->vlib_rp = vlib_rp; am->shmem_hdr = (void *) vlib_rp->user_ctx; } + + if (PREDICT_FALSE (vl_msg_api_fuzz_hook != 0)) + (*vl_msg_api_fuzz_hook) (id, the_msg); + (*handler) (the_msg, vm, node); if (is_private) { @@ -870,6 +876,21 @@ vl_msg_api_queue_handler (svm_queue_t * q) vl_msg_api_handler ((void *) msg); } +u32 +vl_msg_api_max_length (void *mp) +{ + msgbuf_t *mb; + u32 data_len = ~0; + + /* Work out the maximum sane message length, and return it */ + if (PREDICT_TRUE (mp != 0)) + { + mb = (msgbuf_t *) (((u8 *) mp) - offsetof (msgbuf_t, data)); + data_len = clib_net_to_host_u32 (mb->data_len); + } + return data_len; +} + vl_api_trace_t * vl_msg_api_trace_get (api_main_t * am, vl_api_trace_which_t which) { @@ -1132,9 +1153,13 @@ vl_api_format_string (u8 * s, va_list * args) * NOT nul terminated. */ u8 * -vl_api_from_api_to_new_vec (vl_api_string_t * astr) +vl_api_from_api_to_new_vec (void *mp, vl_api_string_t * astr) { u8 *v = 0; + + if (vl_msg_api_max_length (mp) < clib_net_to_host_u32 (astr->length)) + return format (0, "insane astr->length %u%c", + clib_net_to_host_u32 (astr->length), 0); vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length)); return v; } diff --git a/src/vlibapi/api_types.h b/src/vlibapi/api_types.h index 21fcde53b0e..07c7aaba0c5 100644 --- a/src/vlibapi/api_types.h +++ b/src/vlibapi/api_types.h @@ -46,7 +46,7 @@ extern int vl_api_vec_to_api_string (const u8 *vec, vl_api_string_t * str); extern u32 vl_api_string_len (vl_api_string_t * astr); /* Returns new vector. NON nul terminated */ -extern u8 * vl_api_from_api_to_new_vec (vl_api_string_t *astr); +extern u8 * vl_api_from_api_to_new_vec (void *mp, vl_api_string_t *astr); /* Returns new vector. Nul terminated */ extern char * vl_api_from_api_to_new_c_string (vl_api_string_t *astr); |