> Date: Sun, 1 May 2016 23:21:18 +0200 (CEST)
> From: Mark Kettenis <[email protected]>
> 
> Diff below provides a bit more meaningful information in the SCSI
> INQUIRY emulation.  It decodes the JDEC manufacturer ID code and
> provides the product string and revision number as read from the card.
> 
> For example:
> 
> scsibus1 at sdmmc2: 2 targets, initiator 0
> sd0 at scsibus1 targ 1 lun 0: <Sandisk, SA04G, 0006> SCSI2 0/direct fixed
> sd0: 3768MB, 512 bytes/sector, 7716864 sectors
> scsibus2 at sdmmc0: 2 targets, initiator 0
> sd1 at scsibus2 targ 1 lun 0: <Kingston, S10032, 0000> SCSI2 0/direct fixed
> sd1: 29184MB, 512 bytes/sector, 59768832 sectors
> 
> where sd0 is an SD card and sd1 is the eMMC soldered onto the board of
> the machine.
> 
> Note that the strncpy here is safe.  The strings in the scsi inquiry
> page don't have to be nul-terminated.

Theo isn't to thrilled about the use of strncpy(9), which might be
removed in the future.

The diff below uses strlcpy(9) and memcpy(9) in a way that should be
fairly easy to audit.

As a bonus it converts some bzero/bcopy calls into memset/memcpy.

Thoughts?


Index: sdmmc_scsi.c
===================================================================
RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_scsi.c,v
retrieving revision 1.35
diff -u -p -r1.35 sdmmc_scsi.c
--- sdmmc_scsi.c        14 Mar 2015 03:38:49 -0000      1.35
+++ sdmmc_scsi.c        1 May 2016 22:31:27 -0000
@@ -376,8 +376,14 @@ void
 sdmmc_inquiry(struct scsi_xfer *xs)
 {
        struct scsi_link *link = xs->sc_link;
+       struct sdmmc_softc *sc = link->adapter_softc;
+       struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
+       struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target];
        struct scsi_inquiry_data inq;
        struct scsi_inquiry *cdb = (struct scsi_inquiry *)xs->cmd;
+       char vendor[sizeof(inq.vendor) + 1];
+       char product[sizeof(inq.product) + 1];
+       char revision[sizeof(inq.revision) + 1];
 
         if (xs->cmdlen != sizeof(*cdb)) {
                xs->error = XS_DRIVER_STUFFUP;
@@ -389,17 +395,43 @@ sdmmc_inquiry(struct scsi_xfer *xs)
                goto done;
        }
 
-       bzero(&inq, sizeof inq);
+       memset(vendor, 0, sizeof(vendor));
+       memset(product, 0, sizeof(product));
+       memset(revision, 0, sizeof(revision));
+       switch (tgt->card->cid.mid) {
+       case 0x02:
+       case 0x45:
+               strlcpy(vendor, "Sandisk", sizeof(vendor));
+               break;
+       case 0x11:
+               strlcpy(vendor, "Toshiba", sizeof(vendor));
+               break;
+       case 0x13:
+               strlcpy(vendor, "Micron", sizeof(vendor));
+               break;
+       case 0x15:
+               strlcpy(vendor, "Samsung", sizeof(vendor));
+               break;
+       case 0x70:
+               strlcpy(vendor, "Kingston", sizeof(vendor));
+               break;
+       default:
+               strlcpy(vendor, "SD/MMC", sizeof(vendor));
+               break;
+       }
+       strlcpy(product, tgt->card->cid.pnm, sizeof(product));
+       snprintf(revision, sizeof(revision), "%04X", tgt->card->cid.rev);
+
+       memset(&inq, 0, sizeof inq);
        inq.device = T_DIRECT;
        inq.version = 2;
        inq.response_format = 2;
        inq.additional_length = 32;
-       strlcpy(inq.vendor, "SD/MMC ", sizeof(inq.vendor));
-       snprintf(inq.product, sizeof(inq.product),
-           "Drive #%02d", link->target);
-       strlcpy(inq.revision, "   ", sizeof(inq.revision));
+       memcpy(inq.vendor, vendor, sizeof(inq.vendor));
+       memcpy(inq.product, product, sizeof(inq.product));
+       memcpy(inq.revision, revision, sizeof(inq.revision));
 
-       bcopy(&inq, xs->data, MIN(xs->datalen, sizeof(inq)));
+       memcpy(xs->data, &inq, MIN(xs->datalen, sizeof(inq)));
 
 done:
        scsi_done(xs);

Reply via email to