From 9519954ee80e49221f57ae389636e3b010c4f437 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sun, 19 Jun 2011 15:14:35 +0530 Subject: [PATCH] tools/kvm/9p: check the iov count with the read/write count Make sure we don't read/write more than what is requested from client. Signed-off-by: Aneesh Kumar K.V --- tools/kvm/virtio/9p.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c index 24acb585e899..d27017b4cb08 100644 --- a/tools/kvm/virtio/9p.c +++ b/tools/kvm/virtio/9p.c @@ -194,6 +194,22 @@ static void set_p9msg_hdr(struct p9_msg *msg, u32 size, u8 cmd, u16 tag) }; } +static u16 virtio_p9_update_iov_cnt(struct iovec iov[], u32 count, int iov_cnt) +{ + int i; + u32 total = 0; + for (i = 0; (i < iov_cnt) && (total < count); i++) { + if (total + iov[i].iov_len > count) { + /* we don't need this iov fully */ + iov[i].iov_len -= ((total + iov[i].iov_len) - count); + i++; + break; + } + total += iov[i].iov_len; + } + return i; +} + static bool virtio_p9_version(struct p9_dev *p9dev, struct p9_pdu *pdu, u32 *outlen) { @@ -445,6 +461,9 @@ static bool virtio_p9_read(struct p9_dev *p9dev, } else { pdu->in_iov[0].iov_base += VIRTIO_P9_HDR_LEN + sizeof(u32); pdu->in_iov[0].iov_len -= VIRTIO_P9_HDR_LEN + sizeof(u32); + pdu->in_iov_cnt = virtio_p9_update_iov_cnt(pdu->in_iov, + tread->count, + pdu->in_iov_cnt); rread->count = preadv(fid->fd, pdu->in_iov, pdu->in_iov_cnt, tread->offset); if (rread->count > tread->count) @@ -549,6 +568,8 @@ static bool virtio_p9_write(struct p9_dev *p9dev, pdu->out_iov[0].iov_base += (sizeof(*outmsg) + sizeof(*twrite)); pdu->out_iov[0].iov_len -= (sizeof(*outmsg) + sizeof(*twrite)); + pdu->out_iov_cnt = virtio_p9_update_iov_cnt(pdu->out_iov, twrite->count, + pdu->out_iov_cnt); rwrite->count = pwritev(fid->fd, pdu->out_iov, pdu->out_iov_cnt, twrite->offset); *outlen = VIRTIO_P9_HDR_LEN + sizeof(u32); -- 2.39.5