aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlib
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2021-09-08 16:26:52 +0200
committerFlorin Coras <florin.coras@gmail.com>2021-09-09 22:22:53 +0000
commit10bb21fb13aa74dcb0c2c0841d41a698bb274fbe (patch)
treedc96db1f8982973629ddbcacb75dd8e2ba24aaa3 /src/vlib
parent2ac5c11cd32795ec917ff038262aee113d9e792a (diff)
vlib: fix vlib_buffer_enqueue_to_next() overflow
vlib_buffer_enqueue_to_next() requires to allow overflow of up to 63 elements of 'buffer' and 'nexts' array. - add helper to compute the minimum size - fix occurences in session and async crypto Type: fix Change-Id: If8d7eebc5bf9beba71ba194aec0f79b8eb6d5843 Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/vlib')
-rw-r--r--src/vlib/buffer_node.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/vlib/buffer_node.h b/src/vlib/buffer_node.h
index 9ca43d425fc..10ebd253c1b 100644
--- a/src/vlib/buffer_node.h
+++ b/src/vlib/buffer_node.h
@@ -335,6 +335,17 @@ generic_buffer_node_inline (vlib_main_t * vm,
return frame->n_vectors;
}
+/* Minimum size for the 'buffers' and 'nexts' arrays to be used when calling
+ * vlib_buffer_enqueue_to_next().
+ * Because of optimizations, vlib_buffer_enqueue_to_next() will access
+ * past 'count' elements in the 'buffers' and 'nexts' arrays, IOW it
+ * will overflow.
+ * Those overflow elements are ignored in the final result so they do not
+ * need to be properly initialized, however if the array is allocated right
+ * before the end of a page and the next page is not mapped, accessing the
+ * overflow elements will trigger a segfault. */
+#define VLIB_BUFFER_ENQUEUE_MIN_SIZE(n) round_pow2 ((n), 64)
+
static_always_inline void
vlib_buffer_enqueue_to_next (vlib_main_t * vm, vlib_node_runtime_t * node,
u32 * buffers, u16 * nexts, uword count)
@@ -345,6 +356,20 @@ vlib_buffer_enqueue_to_next (vlib_main_t * vm, vlib_node_runtime_t * node,
}
static_always_inline void
+vlib_buffer_enqueue_to_next_vec (vlib_main_t *vm, vlib_node_runtime_t *node,
+ u32 **buffers, u16 **nexts, uword count)
+{
+ const u32 bl = vec_len (*buffers), nl = vec_len (*nexts);
+ const u32 c = VLIB_BUFFER_ENQUEUE_MIN_SIZE (count);
+ ASSERT (bl >= count && nl >= count);
+ vec_validate (*buffers, c);
+ vec_validate (*nexts, c);
+ vlib_buffer_enqueue_to_next (vm, node, *buffers, *nexts, count);
+ vec_set_len (*buffers, bl);
+ vec_set_len (*nexts, nl);
+}
+
+static_always_inline void
vlib_buffer_enqueue_to_single_next (vlib_main_t * vm,
vlib_node_runtime_t * node, u32 * buffers,
u16 next_index, u32 count)