mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-28 22:10:33 +00:00
virtio-9p: break device if buffers are misconfigured
The 9P protocol is transport agnostic: if the guest misconfigured the buffers, the best we can do is to set the broken flag on the device. Signed-off-by: Greg Kurz <groug@kaod.org>
This commit is contained in:
parent
a4d9985450
commit
8d37de41ca
@ -1664,7 +1664,7 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
|
||||
unsigned int niov;
|
||||
|
||||
if (is_write) {
|
||||
pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov);
|
||||
pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov, size + skip);
|
||||
} else {
|
||||
pdu->s->transport->init_in_iov_from_pdu(pdu, &iov, &niov, size + skip);
|
||||
}
|
||||
|
@ -363,7 +363,7 @@ struct V9fsTransport {
|
||||
void (*init_in_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov,
|
||||
unsigned int *pniov, size_t size);
|
||||
void (*init_out_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov,
|
||||
unsigned int *pniov);
|
||||
unsigned int *pniov, size_t size);
|
||||
void (*push_and_notify)(V9fsPDU *pdu);
|
||||
};
|
||||
|
||||
|
@ -146,8 +146,16 @@ static ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
ssize_t ret;
|
||||
|
||||
return v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap);
|
||||
ret = v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap);
|
||||
if (ret < 0) {
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(v);
|
||||
|
||||
virtio_error(vdev, "Failed to encode VirtFS reply type %d",
|
||||
pdu->id + 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
|
||||
@ -156,28 +164,52 @@ static ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
ssize_t ret;
|
||||
|
||||
return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap);
|
||||
ret = v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap);
|
||||
if (ret < 0) {
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(v);
|
||||
|
||||
virtio_error(vdev, "Failed to decode VirtFS request type %d", pdu->id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The size parameter is used by other transports. Do not drop it. */
|
||||
static void virtio_init_in_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
|
||||
unsigned int *pniov, size_t size)
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
size_t buf_size = iov_size(elem->in_sg, elem->in_num);
|
||||
|
||||
if (buf_size < size) {
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(v);
|
||||
|
||||
virtio_error(vdev,
|
||||
"VirtFS reply type %d needs %zu bytes, buffer has %zu",
|
||||
pdu->id + 1, size, buf_size);
|
||||
}
|
||||
|
||||
*piov = elem->in_sg;
|
||||
*pniov = elem->in_num;
|
||||
}
|
||||
|
||||
static void virtio_init_out_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
|
||||
unsigned int *pniov)
|
||||
unsigned int *pniov, size_t size)
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
size_t buf_size = iov_size(elem->out_sg, elem->out_num);
|
||||
|
||||
if (buf_size < size) {
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(v);
|
||||
|
||||
virtio_error(vdev,
|
||||
"VirtFS request type %d needs %zu bytes, buffer has %zu",
|
||||
pdu->id, size, buf_size);
|
||||
}
|
||||
|
||||
*piov = elem->out_sg;
|
||||
*pniov = elem->out_num;
|
||||
|
@ -147,7 +147,8 @@ static ssize_t xen_9pfs_pdu_vunmarshal(V9fsPDU *pdu,
|
||||
|
||||
static void xen_9pfs_init_out_iov_from_pdu(V9fsPDU *pdu,
|
||||
struct iovec **piov,
|
||||
unsigned int *pniov)
|
||||
unsigned int *pniov,
|
||||
size_t size)
|
||||
{
|
||||
Xen9pfsDev *xen_9pfs = container_of(pdu->s, Xen9pfsDev, state);
|
||||
Xen9pfsRing *ring = &xen_9pfs->rings[pdu->tag % xen_9pfs->num_rings];
|
||||
|
Loading…
Reference in New Issue
Block a user