[dpdk-dev] vhost: avoid buffer overflow in update_secure_len
Commit Message
The guest could trigger this buffer overflow by creating a cycle of descriptors
(which would also cause an infinite loop). The more common case is that
vq->avail->idx jumps out of the range [last_used_idx, last_used_idx+256). This
happens nearly every time when restarting a DPDK app inside a VM connected to a
vhost-user vswitch because the virtqueue memory allocated by the previous run
is zeroed.
Signed-off-by: Rich Lane <rlane@bigswitch.com>
---
lib/librte_vhost/vhost_rxtx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On Thu, Nov 12, 2015 at 12:02:33AM -0800, Rich Lane wrote:
> The guest could trigger this buffer overflow by creating a cycle of descriptors
> (which would also cause an infinite loop). The more common case is that
> vq->avail->idx jumps out of the range [last_used_idx, last_used_idx+256). This
> happens nearly every time when restarting a DPDK app inside a VM connected to a
> vhost-user vswitch because the virtqueue memory allocated by the previous run
> is zeroed.
Hi,
I somehow was aware of this issue before while reading the code.
Thinking that we never met that, I delayed the fix (it was still
in my TODO list).
Would you please tell me the steps (commands would be better) to
reproduce your issue? I'd like to know more about the isue: I'm
guessing maybe we need fix it with a bit more cares.
--yliu
>
> Signed-off-by: Rich Lane <rlane@bigswitch.com>
> ---
> lib/librte_vhost/vhost_rxtx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
> index 9322ce6..d95b478 100644
> --- a/lib/librte_vhost/vhost_rxtx.c
> +++ b/lib/librte_vhost/vhost_rxtx.c
> @@ -453,7 +453,7 @@ update_secure_len(struct vhost_virtqueue *vq, uint32_t id,
> vq->buf_vec[vec_id].desc_idx = idx;
> vec_id++;
>
> - if (vq->desc[idx].flags & VRING_DESC_F_NEXT) {
> + if (vq->desc[idx].flags & VRING_DESC_F_NEXT && vec_id < BUF_VECTOR_MAX) {
> idx = vq->desc[idx].next;
> next_desc = 1;
> }
> --
> 1.9.1
@@ -453,7 +453,7 @@ update_secure_len(struct vhost_virtqueue *vq, uint32_t id,
vq->buf_vec[vec_id].desc_idx = idx;
vec_id++;
- if (vq->desc[idx].flags & VRING_DESC_F_NEXT) {
+ if (vq->desc[idx].flags & VRING_DESC_F_NEXT && vec_id < BUF_VECTOR_MAX) {
idx = vq->desc[idx].next;
next_desc = 1;
}