summaryrefslogtreecommitdiff
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2010-09-19 12:08:28 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2010-09-19 12:08:28 +0000
commit51742eaf3894f88c938d5cfe6d024f686b77c132 (patch)
treee1ff47ba3013aa13c210b600af97b0960068652f /sys/dev/ata
parentbed9a661e8d990cb4146facc97deeff605d6958d (diff)
check the cdb length on the scsi commands we emulate in atascsi as a way to
check that the midlayer is doing the right thing. ok krw@
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/atascsi.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/sys/dev/ata/atascsi.c b/sys/dev/ata/atascsi.c
index 6d5a3581b43..bc0369e9f27 100644
--- a/sys/dev/ata/atascsi.c
+++ b/sys/dev/ata/atascsi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atascsi.c,v 1.91 2010/09/02 11:54:44 dlg Exp $ */
+/* $OpenBSD: atascsi.c,v 1.92 2010/09/19 12:08:27 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -514,6 +514,11 @@ atascsi_disk_inq(struct scsi_xfer *xs)
{
struct scsi_inquiry *inq = (struct scsi_inquiry *)xs->cmd;
+ if (xs->cmdlen != sizeof(*inq)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
if (ISSET(inq->flags, SI_EVPD)) {
switch (inq->pagecode) {
case SI_PG_SUPPORTED:
@@ -745,6 +750,11 @@ atascsi_disk_sync(struct scsi_xfer *xs)
struct atascsi *as = link->adapter_softc;
struct ata_xfer *xa = xs->io;
+ if (xs->cmdlen != sizeof(struct scsi_synchronize_cache)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
xa->datalen = 0;
xa->flags = ATA_F_READ;
xa->complete = atascsi_disk_sync_done;
@@ -863,6 +873,11 @@ atascsi_disk_capacity(struct scsi_xfer *xs)
struct scsi_read_cap_data rcd;
u_int64_t capacity;
+ if (xs->cmdlen != sizeof(struct scsi_read_capacity)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
bzero(&rcd, sizeof(rcd));
capacity = ata_identify_blocks(&ap->ap_identify);
if (capacity > 0xffffffff)
@@ -886,6 +901,11 @@ atascsi_disk_capacity16(struct scsi_xfer *xs)
u_int align;
u_int16_t lowest_aligned = 0;
+ if (xs->cmdlen != sizeof(struct scsi_read_capacity_16)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
bzero(&rcd, sizeof(rcd));
_lto8b(ata_identify_blocks(&ap->ap_identify), rcd.addr);
@@ -952,6 +972,11 @@ atascsi_passthru_12(struct scsi_xfer *xs)
struct scsi_ata_passthru_12 *cdb;
struct ata_fis_h2d *fis;
+ if (xs->cmdlen != sizeof(*cdb)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
cdb = (struct scsi_ata_passthru_12 *)xs->cmd;
/* validate cdb */
@@ -982,6 +1007,11 @@ atascsi_passthru_16(struct scsi_xfer *xs)
struct scsi_ata_passthru_16 *cdb;
struct ata_fis_h2d *fis;
+ if (xs->cmdlen != sizeof(*cdb)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
cdb = (struct scsi_ata_passthru_16 *)xs->cmd;
/* validate cdb */
@@ -1059,6 +1089,11 @@ atascsi_disk_start_stop(struct scsi_xfer *xs)
struct ata_xfer *xa = xs->io;
struct scsi_start_stop *ss = (struct scsi_start_stop *)xs->cmd;
+ if (xs->cmdlen != sizeof(*ss)) {
+ atascsi_done(xs, XS_DRIVER_STUFFUP);
+ return;
+ }
+
if (ss->how != SSS_STOP) {
atascsi_done(xs, XS_NOERROR);
return;