summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXie Yongji <xieyongji@bytedance.com>2022-05-05 18:09:10 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-06-14 16:54:01 +0200
commit29c3f932b422d92115e260a250fd910d46cd0c09 (patch)
treec9d1836ddee67cc0dedfb9b488b3d6d122685695
parent3966522c6bf3cc95b3911c75dfc3c131ba577ed9 (diff)
downloadlinux-stable-29c3f932b422d92115e260a250fd910d46cd0c09.tar.gz
linux-stable-29c3f932b422d92115e260a250fd910d46cd0c09.tar.bz2
linux-stable-29c3f932b422d92115e260a250fd910d46cd0c09.zip
vringh: Fix loop descriptors check in the indirect cases
[ Upstream commit dbd29e0752286af74243cf891accf472b2f3edd8 ] We should use size of descriptor chain to test loop condition in the indirect case. And another statistical count is also introduced for indirect descriptors to avoid conflict with the statistical count of direct descriptors. Fixes: f87d0fbb5798 ("vringh: host-side implementation of virtio rings.") Signed-off-by: Xie Yongji <xieyongji@bytedance.com> Signed-off-by: Fam Zheng <fam.zheng@bytedance.com> Message-Id: <20220505100910.137-1-xieyongji@bytedance.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/vhost/vringh.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index c23045aa9873..a764d36c4d38 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -263,7 +263,7 @@ __vringh_iov(struct vringh *vrh, u16 i,
gfp_t gfp,
int (*copy)(void *dst, const void *src, size_t len))
{
- int err, count = 0, up_next, desc_max;
+ int err, count = 0, indirect_count = 0, up_next, desc_max;
struct vring_desc desc, *descs;
struct vringh_range range = { -1ULL, 0 }, slowrange;
bool slow = false;
@@ -320,7 +320,12 @@ __vringh_iov(struct vringh *vrh, u16 i,
continue;
}
- if (count++ == vrh->vring.num) {
+ if (up_next == -1)
+ count++;
+ else
+ indirect_count++;
+
+ if (count > vrh->vring.num || indirect_count > desc_max) {
vringh_bad("Descriptor loop in %p", descs);
err = -ELOOP;
goto fail;
@@ -382,6 +387,7 @@ __vringh_iov(struct vringh *vrh, u16 i,
i = return_from_indirect(vrh, &up_next,
&descs, &desc_max);
slow = false;
+ indirect_count = 0;
} else
break;
}