-/* $OpenBSD: vioscsi.c,v 1.17 2021/04/22 18:40:21 dv Exp $ */
+/* $OpenBSD: vioscsi.c,v 1.18 2021/05/18 11:06:43 dv Exp $ */
/*
* Copyright (c) 2017 Carlos Cardenas <ccardenas@openbsd.org>
}
static struct ioinfo *
-vioscsi_start_read(struct vioscsi_dev *dev, off_t block, ssize_t n_blocks)
+vioscsi_start_read(struct vioscsi_dev *dev, off_t block, size_t n_blocks)
{
struct ioinfo *info;
+ /* Limit to 64M for now */
+ if (n_blocks * VIOSCSI_BLOCK_SIZE_CDROM > (1 << 26)) {
+ log_warnx("%s: read size exceeded 64M", __func__);
+ return (NULL);
+ }
+
info = calloc(1, sizeof(*info));
if (!info)
goto nomem;
vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
"idx %d req_idx %d global_idx %d", __func__, acct->resp_desc->addr,
acct->resp_desc->len, acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto free_inq;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, inq_data, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, inq_data,
+ sizeof(struct scsi_inquiry_data))) {
log_warnx("%s: unable to write inquiry"
" response to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
uint8_t mode_page_ctl;
uint8_t mode_page_code;
uint8_t *mode_reply;
- uint8_t mode_reply_len;
+ uint8_t mode_reply_len = 0;
struct scsi_mode_sense *mode_sense;
memset(&resp, 0, sizeof(resp));
* mode sense header is 4 bytes followed
* by a variable page
* ERR_RECOVERY_PAGE is 12 bytes
- * CDVD_CAPABILITIES_PAGE is 27 bytes
+ * CDVD_CAPABILITIES_PAGE is 32 bytes
*/
switch (mode_page_code) {
case ERR_RECOVERY_PAGE:
*(mode_reply + 7) = MODE_READ_RETRY_COUNT;
break;
case CDVD_CAPABILITIES_PAGE:
- mode_reply_len = 31;
+ mode_reply_len = 36;
mode_reply =
(uint8_t*)calloc(mode_reply_len, sizeof(uint8_t));
if (mode_reply == NULL)
DPRINTF("%s: writing resp to 0x%llx size %d "
"at local idx %d req_idx %d global_idx %d",
- __func__, acct->resp_desc->addr, acct->resp_desc->len,
+ __func__, acct->resp_desc->addr, mode_reply_len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK"
" resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
DPRINTF("%s: writing mode_reply to 0x%llx "
"size %d at local idx %d req_idx %d "
- "global_idx %d",__func__, acct->resp_desc->addr,
- acct->resp_desc->len, acct->resp_idx, acct->req_idx,
- acct->idx);
+ "global_idx %d", __func__, acct->resp_desc->addr,
+ mode_reply_len, acct->resp_idx, acct->req_idx, acct->idx);
if (write_mem(acct->resp_desc->addr, mode_reply,
- acct->resp_desc->len)) {
+ mode_reply_len)) {
log_warnx("%s: unable to write "
"mode_reply to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto mode_sense_out;
uint8_t mode_page_ctl;
uint8_t mode_page_code;
uint8_t *mode_reply;
- uint8_t mode_reply_len;
+ uint8_t mode_reply_len = 0;
uint16_t mode_sense_len;
struct scsi_mode_sense_big *mode_sense_10;
* mode sense header is 8 bytes followed
* by a variable page
* ERR_RECOVERY_PAGE is 12 bytes
- * CDVD_CAPABILITIES_PAGE is 27 bytes
+ * CDVD_CAPABILITIES_PAGE is 32 bytes
*/
switch (mode_page_code) {
case ERR_RECOVERY_PAGE:
*(mode_reply + 11) = MODE_READ_RETRY_COUNT;
break;
case CDVD_CAPABILITIES_PAGE:
- mode_reply_len = 35;
+ mode_reply_len = 40;
mode_reply =
(uint8_t*)calloc(mode_reply_len, sizeof(uint8_t));
if (mode_reply == NULL)
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK"
" resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
DPRINTF("%s: writing mode_reply to 0x%llx "
"size %d at local idx %d req_idx %d global_idx %d",
- __func__, acct->resp_desc->addr, acct->resp_desc->len,
+ __func__, acct->resp_desc->addr, mode_reply_len,
acct->resp_idx, acct->req_idx, acct->idx);
if (write_mem(acct->resp_desc->addr, mode_reply,
- acct->resp_desc->len)) {
+ mode_reply_len)) {
log_warnx("%s: unable to write "
"mode_reply to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto mode_sense_big_out;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto free_read_capacity;
acct->resp_idx, acct->req_idx, acct->idx);
if (write_mem(acct->resp_desc->addr, r_cap_data,
- acct->resp_desc->len)) {
+ sizeof(struct scsi_read_cap_data))) {
log_warnx("%s: unable to write read_cap_data"
" response to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status "
"data @ 0x%llx", __func__, acct->resp_desc->addr);
goto free_read_capacity_16;
acct->resp_idx, acct->req_idx, acct->idx);
if (write_mem(acct->resp_desc->addr, r_cap_data_16,
- acct->resp_desc->len)) {
+ sizeof(struct scsi_read_cap_data_16))) {
log_warnx("%s: unable to write read_cap_data_16"
" response to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR "
"status data @ 0x%llx", __func__,
acct->resp_desc->addr);
}
- reply_rpl = calloc(1, sizeof(*reply_rpl));
+ reply_rpl = calloc(1, sizeof(struct vioscsi_report_luns_data));
if (reply_rpl == NULL) {
log_warnx("%s: cannot alloc reply_rpl", __func__);
"idx %d req_idx %d global_idx %d", __func__, acct->resp_desc->addr,
acct->resp_desc->len, acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto free_rpl;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, reply_rpl, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, reply_rpl,
+ sizeof(struct vioscsi_report_luns_data))) {
log_warnx("%s: unable to write reply_rpl"
" response to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR "
"status data @ 0x%llx", __func__,
acct->resp_desc->addr);
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR "
"status data @ 0x%llx", __func__,
acct->resp_desc->addr);
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status "
"data @ 0x%llx", __func__, acct->resp_desc->addr);
goto free_read_6;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, read_buf,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, read_buf, info->len)) {
log_warnx("%s: unable to write read_buf to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
off_t chunk_offset;
struct ioinfo *info;
struct scsi_rw_10 *read_10;
+ size_t chunk_len = 0;
memset(&resp, 0, sizeof(resp));
read_10 = (struct scsi_rw_10 *)(req->cdb);
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status "
"data @ 0x%llx", __func__, acct->resp_desc->addr);
goto free_read_10;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr,
- read_buf + chunk_offset, acct->resp_desc->len)) {
+ /* Check we don't read beyond read_buf boundaries. */
+ if (acct->resp_desc->len > info->len - chunk_offset) {
+ log_warnx("%s: descriptor length beyond read_buf len",
+ __func__);
+ chunk_len = info->len - chunk_offset;
+ } else
+ chunk_len = acct->resp_desc->len;
+
+ if (write_mem(acct->resp_desc->addr, read_buf + chunk_offset,
+ chunk_len)) {
log_warnx("%s: unable to write read_buf"
" to gpa @ 0x%llx", __func__,
acct->resp_desc->addr);
dev->locked = dev->locked ? 0 : 1;
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
mech_status_len = (uint16_t)_2btol(mech_status->length);
DPRINTF("%s: MECH_STATUS Len %u", __func__, mech_status_len);
- mech_status_header = calloc(1, sizeof(*mech_status_header));
+ mech_status_header = calloc(1,
+ sizeof(struct scsi_mechanism_status_header));
if (mech_status_header == NULL)
goto mech_out;
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto free_mech;
&(acct->resp_idx));
if (write_mem(acct->resp_desc->addr, mech_status_header,
- acct->resp_desc->len)) {
+ sizeof(struct scsi_mechanism_status_header))) {
log_warnx("%s: unable to write "
"mech_status_header response to "
"gpa @ 0x%llx",
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto read_toc_out;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto read_toc_out;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, toc_data,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, toc_data, sizeof(toc_data))) {
log_warnx("%s: unable to write toc descriptor data @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
} else {
acct->resp_desc = vioscsi_next_ring_desc(acct->desc,
acct->req_desc, &(acct->resp_idx));
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set ERR status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto gesn_out;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to write OK resp status "
"data @ 0x%llx", __func__, acct->resp_desc->addr);
goto gesn_out;
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, gesn_reply,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, gesn_reply, sizeof(gesn_reply))) {
log_warnx("%s: unable to write gesn_reply"
" response to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
- if (write_mem(acct->resp_desc->addr, &resp,
- acct->resp_desc->len)) {
+ if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) {
log_warnx("%s: unable to set Ok status data @ 0x%llx",
__func__, acct->resp_desc->addr);
goto free_get_config;
acct->resp_idx, acct->req_idx, acct->idx);
if (write_mem(acct->resp_desc->addr, get_conf_reply,
- acct->resp_desc->len)) {
+ G_CONFIG_REPLY_SIZE)) {
log_warnx("%s: unable to write get_conf_reply"
" response to gpa @ 0x%llx",
__func__, acct->resp_desc->addr);
}
/* Read command from descriptor ring */
- if (read_mem(acct.req_desc->addr, &req, acct.req_desc->len)) {
+ if (read_mem(acct.req_desc->addr, &req, sizeof(req))) {
log_warnx("%s: command read_mem error @ 0x%llx",
__func__, acct.req_desc->addr);
goto out;
vioscsi_prepare_resp(&resp,
VIRTIO_SCSI_S_BAD_TARGET, SCSI_OK, 0, 0, 0);
+ if (acct.resp_desc->len > sizeof(resp)) {
+ log_warnx("%s: invalid descriptor length",
+ __func__);
+ goto out;
+ }
if (write_mem(acct.resp_desc->addr, &resp,
- acct.resp_desc->len)) {
+ sizeof(resp))) {
log_warnx("%s: unable to write BAD_TARGET"
" resp status data @ 0x%llx",
__func__, acct.resp_desc->addr);
-/* $OpenBSD: virtio.c,v 1.86 2021/04/22 18:40:21 dv Exp $ */
+/* $OpenBSD: virtio.c,v 1.87 2021/05/18 11:06:43 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
if (rnd_data != NULL) {
arc4random_buf(rnd_data, desc[avail->ring[aidx]].len);
- if (write_mem(desc[avail->ring[aidx]].addr,
- rnd_data, desc[avail->ring[aidx]].len)) {
+ if (write_mem(desc[avail->ring[aidx]].addr, rnd_data, sz)) {
log_warnx("viornd: can't write random data @ "
"0x%llx",
desc[avail->ring[aidx]].addr);
{
struct ioinfo *info;
+ /* Limit to 64M for now */
+ if (sz > (1 << 26)) {
+ log_warnx("%s: read size exceeded 64M", __func__);
+ return (NULL);
+ }
+
info = calloc(1, sizeof(*info));
if (!info)
goto nomem;
{
struct ioinfo *info;
+ /* Limit to 64M for now */
+ if (len > (1 << 26)) {
+ log_warnx("%s: write size exceeded 64M", __func__);
+ return (NULL);
+ }
+
info = calloc(1, sizeof(*info));
if (!info)
goto nomem;
+
info->buf = malloc(len);
if (info->buf == NULL)
goto nomem;
info->offset = sector * VIRTIO_BLK_SECTOR_SIZE;
info->file = &dev->file;
- if (read_mem(addr, info->buf, len)) {
+ if (read_mem(addr, info->buf, info->len)) {
vioblk_free_info(info);
return NULL;
}
/*
* XXX in various cases, ds should be set to VIRTIO_BLK_S_IOERR, if we can
- * XXX cant trust ring data from VM, be extra cautious.
*/
int
vioblk_notifyq(struct vioblk_dev *dev)
}
/* Read command from descriptor ring */
- if (read_mem(cmd_desc->addr, &cmd, cmd_desc->len)) {
+ if (read_mem(cmd_desc->addr, &cmd, sizeof(cmd))) {
log_warnx("vioblk: command read_mem error @ 0x%llx",
cmd_desc->addr);
goto out;
}
if (write_mem(secdata_desc->addr, secdata,
- secdata_desc->len)) {
+ secdata_desc->len)) {
log_warnx("can't write sector "
"data to gpa @ 0x%llx",
secdata_desc->addr);
ds_desc = secdata_desc;
ds = VIRTIO_BLK_S_OK;
- if (write_mem(ds_desc->addr, &ds, ds_desc->len)) {
+ if (write_mem(ds_desc->addr, &ds, sizeof(ds))) {
log_warnx("can't write device status data @ "
"0x%llx", ds_desc->addr);
dump_descriptor_chain(desc, cmd_desc_idx);
ds_desc = secdata_desc;
ds = VIRTIO_BLK_S_OK;
- if (write_mem(ds_desc->addr, &ds, ds_desc->len)) {
+ if (write_mem(ds_desc->addr, &ds, sizeof(ds))) {
log_warnx("wr vioblk: can't write device "
"status data @ 0x%llx", ds_desc->addr);
dump_descriptor_chain(desc, cmd_desc_idx);
ds_desc = &desc[ds_desc_idx];
ds = VIRTIO_BLK_S_OK;
- if (write_mem(ds_desc->addr, &ds, ds_desc->len)) {
+ if (write_mem(ds_desc->addr, &ds, sizeof(ds))) {
log_warnx("fl vioblk: "
"can't write device status "
"data @ 0x%llx", ds_desc->addr);
ret = 0;
- if (sz < 1) {
+ if (sz < 1 || sz > IP_MAXPACKET + ETHER_HDR_LEN) {
log_warn("%s: invalid packet size", __func__);
return (0);
}
/* Write out virtio header */
if (write_mem(hdr_desc->addr, &hdr, sizeof(struct virtio_net_hdr))) {
- log_warnx("vionet: rx enq header write_mem error @ "
+ log_warnx("vionet: rx enq header write_mem error @ "
"0x%llx", hdr_desc->addr);
goto out;
}
if (rem >= sz) {
if (write_mem(hdr_desc->addr + sizeof(struct virtio_net_hdr),
- pkt, sz)) {
+ pkt, sz)) {
log_warnx("vionet: rx enq packet write_mem error @ "
"0x%llx", pkt_desc->addr);
goto out;
/*
* Must be called with dev->mutex acquired.
- *
- * XXX cant trust ring data from VM, be extra cautious.
*/
int
vionet_notify_tx(struct vionet_dev *dev)
uint64_t q_gpa;
uint32_t vr_sz;
uint16_t idx, pkt_desc_idx, hdr_desc_idx, dxx, cnt;
- size_t pktsz;
+ size_t pktsz, chunk_size = 0;
ssize_t dhcpsz;
int ret, num_enq, ofs, spc;
char *vr, *pkt, *dhcppkt;
goto out;
}
+ /* Check we don't read beyond allocated pktsz */
+ if (pkt_desc->len > pktsz - ofs) {
+ log_warnx("%s: descriptor len past pkt len",
+ __func__);
+ chunk_size = pktsz - ofs - pkt_desc->len;
+ } else
+ chunk_size = pkt_desc->len;
+
/* Read packet from descriptor ring */
- if (read_mem(pkt_desc->addr, pkt + ofs,
- pkt_desc->len)) {
+ if (read_mem(pkt_desc->addr, pkt + ofs, chunk_size)) {
log_warnx("vionet: packet read_mem error "
"@ 0x%llx", pkt_desc->addr);
goto out;
goto out;
}
+ /* Check we don't read beyond allocated pktsz */
+ if (pkt_desc->len > pktsz - ofs) {
+ log_warnx("%s: descriptor len past pkt len", __func__);
+ chunk_size = pktsz - ofs - pkt_desc->len;
+ } else
+ chunk_size = pkt_desc->len;
+
/* Read packet from descriptor ring */
- if (read_mem(pkt_desc->addr, pkt + ofs,
- pkt_desc->len)) {
+ if (read_mem(pkt_desc->addr, pkt + ofs, chunk_size)) {
log_warnx("vionet: packet read_mem error @ "
"0x%llx", pkt_desc->addr);
goto out;