Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153414874
D18465.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D18465.id.diff
View Options
Index: head/usr.sbin/bhyve/iov.h
===================================================================
--- head/usr.sbin/bhyve/iov.h
+++ head/usr.sbin/bhyve/iov.h
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2016 Jakub Klama <jceel@FreeBSD.org>.
+ * Copyright (c) 2018 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,12 +33,12 @@
#ifndef _IOV_H_
#define _IOV_H_
-void seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2,
- size_t *niov2, size_t seek);
-size_t truncate_iov(struct iovec *iov, size_t niov, size_t length);
-size_t count_iov(struct iovec *iov, size_t niov);
-ssize_t iov_to_buf(struct iovec *iov, size_t niov, void **buf);
-ssize_t buf_to_iov(void *buf, size_t buflen, struct iovec *iov, size_t niov,
+void seek_iov(const struct iovec *iov1, int niov1, struct iovec *iov2,
+ int *niov2, size_t seek);
+void truncate_iov(struct iovec *iov, int *niov, size_t length);
+size_t count_iov(const struct iovec *iov, int niov);
+ssize_t iov_to_buf(const struct iovec *iov, int niov, void **buf);
+ssize_t buf_to_iov(const void *buf, size_t buflen, struct iovec *iov, int niov,
size_t seek);
#endif /* _IOV_H_ */
Index: head/usr.sbin/bhyve/iov.c
===================================================================
--- head/usr.sbin/bhyve/iov.c
+++ head/usr.sbin/bhyve/iov.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2016 Jakub Klama <jceel@FreeBSD.org>.
+ * Copyright (c) 2018 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,12 +40,12 @@
#include "iov.h"
void
-seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2, size_t *niov2,
+seek_iov(const struct iovec *iov1, int niov1, struct iovec *iov2, int *niov2,
size_t seek)
{
size_t remainder = 0;
size_t left = seek;
- size_t i, j;
+ int i, j;
for (i = 0; i < niov1; i++) {
size_t toseek = MIN(left, iov1[i].iov_len);
@@ -69,9 +70,10 @@
}
size_t
-count_iov(struct iovec *iov, size_t niov)
+count_iov(const struct iovec *iov, int niov)
{
- size_t i, total = 0;
+ size_t total = 0;
+ int i;
for (i = 0; i < niov; i++)
total += iov[i].iov_len;
@@ -79,35 +81,36 @@
return (total);
}
-size_t
-truncate_iov(struct iovec *iov, size_t niov, size_t length)
+void
+truncate_iov(struct iovec *iov, int *niov, size_t length)
{
- size_t i, done = 0;
+ size_t done = 0;
+ int i;
- for (i = 0; i < niov; i++) {
+ for (i = 0; i < *niov; i++) {
size_t toseek = MIN(length - done, iov[i].iov_len);
done += toseek;
- if (toseek < iov[i].iov_len) {
+ if (toseek <= iov[i].iov_len) {
iov[i].iov_len = toseek;
- return (i + 1);
+ *niov = i + 1;
+ return;
}
}
-
- return (niov);
}
ssize_t
-iov_to_buf(struct iovec *iov, size_t niov, void **buf)
+iov_to_buf(const struct iovec *iov, int niov, void **buf)
{
- size_t i, ptr = 0, total = 0;
+ size_t ptr, total;
+ int i;
- for (i = 0; i < niov; i++) {
- total += iov[i].iov_len;
- *buf = realloc(*buf, total);
- if (*buf == NULL)
- return (-1);
+ total = count_iov(iov, niov);
+ *buf = realloc(*buf, total);
+ if (*buf == NULL)
+ return (-1);
+ for (i = 0, ptr = 0; i < niov; i++) {
memcpy(*buf + ptr, iov[i].iov_base, iov[i].iov_len);
ptr += iov[i].iov_len;
}
@@ -116,12 +119,12 @@
}
ssize_t
-buf_to_iov(void *buf, size_t buflen, struct iovec *iov, size_t niov,
+buf_to_iov(const void *buf, size_t buflen, struct iovec *iov, int niov,
size_t seek)
{
struct iovec *diov;
- size_t ndiov, i;
- uintptr_t off = 0;
+ int ndiov, i;
+ size_t off = 0, len;
if (seek > 0) {
diov = malloc(sizeof(struct iovec) * niov);
@@ -131,10 +134,14 @@
ndiov = niov;
}
- for (i = 0; i < ndiov; i++) {
- memcpy(diov[i].iov_base, buf + off, diov[i].iov_len);
- off += diov[i].iov_len;
+ for (i = 0; i < ndiov && off < buflen; i++) {
+ len = MIN(diov[i].iov_len, buflen - off);
+ memcpy(diov[i].iov_base, buf + off, len);
+ off += len;
}
+
+ if (seek > 0)
+ free(diov);
return ((ssize_t)off);
}
Index: head/usr.sbin/bhyve/pci_virtio_scsi.c
===================================================================
--- head/usr.sbin/bhyve/pci_virtio_scsi.c
+++ head/usr.sbin/bhyve/pci_virtio_scsi.c
@@ -462,7 +462,7 @@
struct pci_vtscsi_req_cmd_wr *cmd_wr;
struct iovec data_iov_in[VTSCSI_MAXSEG], data_iov_out[VTSCSI_MAXSEG];
union ctl_io *io;
- size_t data_niov_in, data_niov_out;
+ int data_niov_in, data_niov_out;
void *ext_data_ptr = NULL;
uint32_t ext_data_len = 0, ext_sg_entries = 0;
int err;
@@ -472,8 +472,8 @@
seek_iov(iov_out, niov_out, data_iov_out, &data_niov_out,
VTSCSI_OUT_HEADER_LEN(sc));
- truncate_iov(iov_in, niov_in, VTSCSI_IN_HEADER_LEN(sc));
- truncate_iov(iov_out, niov_out, VTSCSI_OUT_HEADER_LEN(sc));
+ truncate_iov(iov_in, &niov_in, VTSCSI_IN_HEADER_LEN(sc));
+ truncate_iov(iov_out, &niov_out, VTSCSI_OUT_HEADER_LEN(sc));
iov_to_buf(iov_in, niov_in, (void **)&cmd_rd);
cmd_wr = malloc(VTSCSI_OUT_HEADER_LEN(sc));
@@ -552,7 +552,8 @@
n = vq_getchain(vq, &idx, iov, VTSCSI_MAXSEG, NULL);
bufsize = iov_to_buf(iov, n, &buf);
iolen = pci_vtscsi_control_handle(sc, buf, bufsize);
- buf_to_iov(buf + bufsize - iolen, iolen, iov, n, iolen);
+ buf_to_iov(buf + bufsize - iolen, iolen, iov, n,
+ bufsize - iolen);
/*
* Release this chain and handle more
@@ -560,6 +561,7 @@
vq_relchain(vq, idx, iolen);
}
vq_endchains(vq, 1); /* Generate interrupt if appropriate. */
+ free(buf);
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 1:03 AM (2 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31943622
Default Alt Text
D18465.id.diff (5 KB)
Attached To
Mode
D18465: Several iov handling bugs in bhyve virtio-scsi backend
Attached
Detach File
Event Timeline
Log In to Comment