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:52:41 +0200
commit45984b3ae9d688a913d024551848d068b1c0ac4e (patch)
treee689d00c8dcb343c9b86c50efad652f8cbae74e0
parent2811cda7d2ec8c77493b95a7d871e93f412a03a4 (diff)
downloadlinux-stable-45984b3ae9d688a913d024551848d068b1c0ac4e.tar.gz
linux-stable-45984b3ae9d688a913d024551848d068b1c0ac4e.tar.bz2
linux-stable-45984b3ae9d688a913d024551848d068b1c0ac4e.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 da47542496cc..63f0ab3e6f63 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -262,7 +262,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;
@@ -319,7 +319,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;
@@ -381,6 +386,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;
}