summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2021-05-12 14:51:29 +0200
committerBeno�t Ganne <bganne@cisco.com>2021-05-17 08:46:29 +0000
commit637c97c7d05813ee2cd60c07746ae6205fbb4202 (patch)
tree71ffb530c6f12dea6b17c6c257f6aa143c0f9f02 /src/vnet
parentaf97221c6ae8f08716b3de212fa111b13282f241 (diff)
virtio: add the checks for descriptors chain len
Type: fix virtio uses indirect descriptors for chain buffers. indirect descriptor chain is mapped on a vlib_buffer_t. Single descriptor is 16 bytes and vlib_buffer_t has 2048 bytes space. So maximum long chain can have 128 (=2048/16) indirect descriptors. This patch adds check to make sure descriptors chain len should not exceed 128. Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com> Change-Id: I060cfb7709568f42c9b5634527172690ce66a1a3
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/devices/virtio/device.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c
index 666cd1631cf..aa816e2e17d 100644
--- a/src/vnet/devices/virtio/device.c
+++ b/src/vnet/devices/virtio/device.c
@@ -31,6 +31,8 @@
#include <vnet/udp/udp_packet.h>
#include <vnet/devices/virtio/virtio.h>
+#define VIRTIO_TX_MAX_CHAIN_LEN 127
+
#define foreach_virtio_tx_func_error \
_(NO_FREE_SLOTS, "no free tx slots") \
_(TRUNC_PACKET, "packet > buffer size -- truncated in tx ring") \
@@ -478,6 +480,13 @@ add_buffer_to_slot (vlib_main_t *vm, vlib_node_runtime_t *node,
b = vlib_get_buffer (vm, b->next_buffer);
id->addr = vlib_buffer_get_current_pa (vm, b);
id->len = b->current_length;
+ if (PREDICT_FALSE (count == VIRTIO_TX_MAX_CHAIN_LEN))
+ {
+ if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
+ vlib_error_count (vm, node->node_index,
+ VIRTIO_TX_ERROR_TRUNC_PACKET, 1);
+ break;
+ }
}
}
else /* VIRTIO_IF_TYPE_[TAP | TUN] */
@@ -496,6 +505,13 @@ add_buffer_to_slot (vlib_main_t *vm, vlib_node_runtime_t *node,
b = vlib_get_buffer (vm, b->next_buffer);
id->addr = pointer_to_uword (vlib_buffer_get_current (b));
id->len = b->current_length;
+ if (PREDICT_FALSE (count == VIRTIO_TX_MAX_CHAIN_LEN))
+ {
+ if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
+ vlib_error_count (vm, node->node_index,
+ VIRTIO_TX_ERROR_TRUNC_PACKET, 1);
+ break;
+ }
}
}
id->flags = 0;
@@ -670,6 +686,13 @@ add_buffer_to_slot_packed (vlib_main_t *vm, vlib_node_runtime_t *node,
b = vlib_get_buffer (vm, b->next_buffer);
id->addr = vlib_buffer_get_current_pa (vm, b);
id->len = b->current_length;
+ if (PREDICT_FALSE (count == VIRTIO_TX_MAX_CHAIN_LEN))
+ {
+ if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
+ vlib_error_count (vm, node->node_index,
+ VIRTIO_TX_ERROR_TRUNC_PACKET, 1);
+ break;
+ }
}
}
id->flags = 0;