aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2018-12-12 08:29:41 -0500
committerOle Troan <ot@cisco.com>2019-03-01 08:51:15 +0100
commitca561dffe1888021d48ad8020fdd8c3b13ff17de (patch)
tree649b1594620d4bb9171125d5942decbc995ecf2a
parent1dd1a77cfd210a40deb0f5ed5ea59621ac644320 (diff)
VPP-1529: check hop-by-hop header length
Fix a single packet-of-death case, caught by vlib_buffer_advance() in debug images. Change-Id: I9c107f20d7c053c3e40a0756dd7ca1c3be276a1a Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/plugins/ioam/udp-ping/udp_ping_node.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/src/plugins/ioam/udp-ping/udp_ping_node.c b/src/plugins/ioam/udp-ping/udp_ping_node.c
index 7a725258d65..59e4511eb7d 100644
--- a/src/plugins/ioam/udp-ping/udp_ping_node.c
+++ b/src/plugins/ioam/udp-ping/udp_ping_node.c
@@ -38,6 +38,23 @@ typedef enum
UDP_PING_N_NEXT,
} udp_ping_next_t;
+#define foreach_udp_ping_error \
+_(BADHBH, "Malformed hop-by-hop header")
+
+typedef enum
+{
+#define _(sym,str) UDP_PING_ERROR_##sym,
+ foreach_udp_ping_error
+#undef _
+ UDP_PING_N_ERROR,
+} udp_ping_error_t;
+
+static char *udp_ping_error_strings[] = {
+#define _(sym,string) string,
+ foreach_udp_ping_error
+#undef _
+};
+
udp_ping_main_t udp_ping_main;
uword
@@ -502,15 +519,26 @@ udp_ping_analyse_hbh (vlib_buffer_t * b0,
*
*/
void
-udp_ping_local_analyse (vlib_buffer_t * b0,
- ip6_header_t * ip0,
- ip6_hop_by_hop_header_t * hbh0, u16 * next0)
+udp_ping_local_analyse (vlib_node_runtime_t * node, vlib_buffer_t * b0,
+ ip6_header_t * ip0, ip6_hop_by_hop_header_t * hbh0,
+ u16 * next0)
{
ip6_main_t *im = &ip6_main;
ip_lookup_main_t *lm = &im->lookup_main;
*next0 = UDP_PING_NEXT_IP6_DROP;
+ /*
+ * Sanity check: hbh header length must be less than
+ * b0->current_length.
+ */
+ if (PREDICT_FALSE ((hbh0->length + 1) << 3) >= b0->current_length)
+ {
+ *next0 = UDP_PING_NEXT_DROP;
+ b0->error = node->errors[UDP_PING_ERROR_BADHBH];
+ return;
+ }
+
if (PREDICT_TRUE (hbh0->protocol == IP_PROTOCOL_UDP))
{
ip6_hop_by_hop_option_t *opt0;
@@ -600,7 +628,7 @@ end:
* @par Graph mechanics: buffer, next index usage
*
* <em>Uses:</em>
- * - <code>udp_ping_local_analyse(p0, ip0, hbh0, &next0)</code>
+ * - <code>udp_ping_local_analyse(node, p0, ip0, hbh0, &next0)</code>
* - Checks packet type - request/respnse and process them.
*
* <em>Next Index:</em>
@@ -660,8 +688,8 @@ udp_ping_local_node_fn (vlib_main_t * vm,
hbh0 = (ip6_hop_by_hop_header_t *) (ip0 + 1);
hbh1 = (ip6_hop_by_hop_header_t *) (ip1 + 1);
- udp_ping_local_analyse (p0, ip0, hbh0, &next0);
- udp_ping_local_analyse (p1, ip1, hbh1, &next1);
+ udp_ping_local_analyse (node, p0, ip0, hbh0, &next0);
+ udp_ping_local_analyse (node, p1, ip1, hbh1, &next1);
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
{
@@ -727,7 +755,7 @@ udp_ping_local_node_fn (vlib_main_t * vm,
ip0 = vlib_buffer_get_current (p0);
hbh0 = (ip6_hop_by_hop_header_t *) (ip0 + 1);
- udp_ping_local_analyse (p0, ip0, hbh0, &next0);
+ udp_ping_local_analyse (node, p0, ip0, hbh0, &next0);
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
{
@@ -774,6 +802,8 @@ VLIB_REGISTER_NODE (udp_ping_local, static) =
.format_trace = format_udp_ping_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
.n_next_nodes = UDP_PING_N_NEXT,
+ .n_errors = UDP_PING_N_ERROR,
+ .error_strings = udp_ping_error_strings,
.next_nodes =
{
[UDP_PING_NEXT_DROP] = "error-drop",