aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlibapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/vlibapi')
-rw-r--r--src/vlibapi/api.h1
-rw-r--r--src/vlibapi/api_shared.c27
-rw-r--r--src/vlibapi/api_types.h2
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);