Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144618949
D53470.1775812633.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D53470.1775812633.diff
View Options
diff --git a/usr.sbin/bhyve/pci_virtio_scsi.c b/usr.sbin/bhyve/pci_virtio_scsi.c
--- a/usr.sbin/bhyve/pci_virtio_scsi.c
+++ b/usr.sbin/bhyve/pci_virtio_scsi.c
@@ -170,10 +170,10 @@
#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11
struct pci_vtscsi_ctrl_tmf {
- uint32_t type;
- uint32_t subtype;
- uint8_t lun[8];
- uint64_t id;
+ const uint32_t type;
+ const uint32_t subtype;
+ const uint8_t lun[8];
+ const uint64_t id;
uint8_t response;
} __attribute__((packed));
@@ -186,9 +186,9 @@
#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY 64
struct pci_vtscsi_ctrl_an {
- uint32_t type;
- uint8_t lun[8];
- uint32_t event_requested;
+ const uint32_t type;
+ const uint8_t lun[8];
+ const uint32_t event_requested;
uint32_t event_actual;
uint8_t response;
} __attribute__((packed));
@@ -219,12 +219,12 @@
} __attribute__((packed));
struct pci_vtscsi_req_cmd_rd {
- uint8_t lun[8];
- uint64_t id;
- uint8_t task_attr;
- uint8_t prio;
- uint8_t crn;
- uint8_t cdb[];
+ const uint8_t lun[8];
+ const uint64_t id;
+ const uint8_t task_attr;
+ const uint8_t prio;
+ const uint8_t crn;
+ const uint8_t cdb[];
} __attribute__((packed));
struct pci_vtscsi_req_cmd_wr {
@@ -241,7 +241,10 @@
static void pci_vtscsi_neg_features(void *, uint64_t);
static int pci_vtscsi_cfgread(void *, int, int, uint32_t *);
static int pci_vtscsi_cfgwrite(void *, int, int, uint32_t);
-static inline int pci_vtscsi_get_lun(uint8_t *);
+
+static inline bool pci_vtscsi_check_lun(const uint8_t *);
+static inline int pci_vtscsi_get_lun(const uint8_t *);
+
static void pci_vtscsi_control_handle(struct pci_vtscsi_softc *, void *, size_t);
static void pci_vtscsi_tmf_handle(struct pci_vtscsi_softc *,
struct pci_vtscsi_ctrl_tmf *);
@@ -368,9 +371,58 @@
return (0);
}
+/*
+ * Check that the given LUN address conforms to the virtio spec, does not
+ * address a target other than 0, and especially does not address the
+ * REPORT_LUNS well-known logical unit.
+ */
+static inline bool
+pci_vtscsi_check_lun(const uint8_t *lun)
+{
+ /*
+ * The virtio spec says that we SHOULD implement the REPORT_LUNS well-
+ * known logical unit, but we currently don't.
+ */
+ if (lun[0] == 0xC1)
+ return (false);
+
+ /* A well-formed LUN address begins with 0x01. */
+ if (lun[0] != 0x01)
+ return (false);
+
+ /* Next comes the target. We currently only support target 0. */
+ if (lun[1] != 0x00)
+ return (false);
+
+ /*
+ * Next two bytes contain the LUN. The virtio spec only says that
+ * these represent a "single-level LUN structure".
+ *
+ * There are several single-level LUN formats, selected by the two MSB
+ * of lun[2]:
+ * 0 0: single-level LUN, peripheral device addressing (0 - 255)
+ * 0 1: single-level LUN, flat space addressing (0 - 16383)
+ * 1 1: single-level LUN, extended flat space addressing (> 16383)
+ *
+ * Since the virtio spec says that it supports up to 16384 LUNs,
+ * it apparently does not support extended flat space addressing.
+ */
+ if (lun[2] != 0x00 && (lun[2] & 0xc0) != 0x40)
+ return (false);
+
+ /* The remaining four bytes must be zero. */
+ if (lun[4] != 0 || lun[5] != 0 || lun[6] != 0 || lun[7] != 0)
+ return (false);
+
+ return (true);
+}
+
static inline int
-pci_vtscsi_get_lun(uint8_t *lun)
+pci_vtscsi_get_lun(const uint8_t *lun)
{
+ assert(lun[0] == 0x01);
+ assert(lun[1] == 0x00);
+ assert(lun[2] == 0x00 || (lun[2] & 0xc0) == 0x40);
return (((lun[2] << 8) | lun[3]) & 0x3fff);
}
@@ -414,6 +466,16 @@
union ctl_io *io;
int err;
+ if (pci_vtscsi_check_lun(tmf->lun) == false) {
+ WPRINTF("TMF request to invalid LUN %.2hhx%.2hhx-%.2hhx%.2hhx-"
+ "%.2hhx%.2hhx-%.2hhx%.2hhx", tmf->lun[0], tmf->lun[1],
+ tmf->lun[2], tmf->lun[3], tmf->lun[4], tmf->lun[5],
+ tmf->lun[6], tmf->lun[7]);
+
+ tmf->response = VIRTIO_SCSI_S_BAD_TARGET;
+ return;
+ }
+
io = ctl_scsi_alloc_io(sc->vss_iid);
if (io == NULL) {
WPRINTF("failed to allocate ctl_io: err=%d (%s)",
@@ -640,6 +702,19 @@
assert(iov_to_buf(req->vsr_iov_in, req->vsr_niov_in,
(void **)&req->vsr_cmd_rd) == VTSCSI_IN_HEADER_LEN(q->vsq_sc));
+ /* Make sure this request addresses a valid LUN. */
+ if (pci_vtscsi_check_lun(req->vsr_cmd_rd->lun) == false) {
+ WPRINTF("I/O request to invalid LUN "
+ "%.2hhx%.2hhx-%.2hhx%.2hhx-%.2hhx%.2hhx-%.2hhx%.2hhx",
+ req->vsr_cmd_rd->lun[0], req->vsr_cmd_rd->lun[1],
+ req->vsr_cmd_rd->lun[2], req->vsr_cmd_rd->lun[3],
+ req->vsr_cmd_rd->lun[4], req->vsr_cmd_rd->lun[5],
+ req->vsr_cmd_rd->lun[6], req->vsr_cmd_rd->lun[7]);
+ req->vsr_cmd_wr->response = VIRTIO_SCSI_S_BAD_TARGET;
+ pci_vtscsi_return_request(q, req, 1);
+ return;
+ }
+
pthread_mutex_lock(&q->vsq_rmtx);
pci_vtscsi_put_request(&q->vsq_requests, req);
pthread_cond_signal(&q->vsq_cv);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 10, 9:17 AM (3 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28315172
Default Alt Text
D53470.1775812633.diff (4 KB)
Attached To
Mode
D53470: bhyve/virtio-scsi: check LUN address validity
Attached
Detach File
Event Timeline
Log In to Comment