From 637c97c7d05813ee2cd60c07746ae6205fbb4202 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Wed, 12 May 2021 14:51:29 +0200 Subject: [PATCH] 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 Change-Id: I060cfb7709568f42c9b5634527172690ce66a1a3 --- src/vnet/devices/virtio/device.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) 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 #include +#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; -- 2.16.6