summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2014-04-15 08:02:57 +0000
committerscottl <scottl@FreeBSD.org>2014-04-15 08:02:57 +0000
commit425242a21051eca15973e52d933fedb19a28fc9e (patch)
tree28f56b06e32af739ce4110eb12f1055513c8939c
parentd06a5364e17ff063e07e31b5fe45847341006157 (diff)
downloadFreeBSD-src-425242a21051eca15973e52d933fedb19a28fc9e.zip
FreeBSD-src-425242a21051eca15973e52d933fedb19a28fc9e.tar.gz
MFC r264229
Add some assertions to ensure that the target array doesn't get accessed out of bounds.
-rw-r--r--sys/dev/mps/mps_sas.c40
-rw-r--r--sys/dev/mps/mps_sas.h1
2 files changed, 35 insertions, 6 deletions
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index b3cf011..32e6959 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -154,7 +154,7 @@ mpssas_find_target_by_handle(struct mpssas_softc *sassc, int start, uint16_t han
struct mpssas_target *target;
int i;
- for (i = start; i < sassc->sc->facts->MaxTargets; i++) {
+ for (i = start; i < sassc->maxtargets; i++) {
target = &sassc->targets[i];
if (target->handle == handle)
return (target);
@@ -709,8 +709,16 @@ mps_attach_sas(struct mps_softc *sc)
__func__, __LINE__);
return (ENOMEM);
}
+
+ /*
+ * XXX MaxTargets could change during a reinit. Since we don't
+ * resize the targets[] array during such an event, cache the value
+ * of MaxTargets here so that we don't get into trouble later. This
+ * should move into the reinit logic.
+ */
+ sassc->maxtargets = sc->facts->MaxTargets;
sassc->targets = malloc(sizeof(struct mpssas_target) *
- sc->facts->MaxTargets, M_MPT2, M_WAITOK|M_ZERO);
+ sassc->maxtargets, M_MPT2, M_WAITOK|M_ZERO);
if(!sassc->targets) {
device_printf(sc->mps_dev, "Cannot allocate memory %s %d\n",
__func__, __LINE__);
@@ -868,7 +876,7 @@ mps_detach_sas(struct mps_softc *sc)
if (sassc->devq != NULL)
cam_simq_free(sassc->devq);
- for(i=0; i< sc->facts->MaxTargets ;i++) {
+ for(i=0; i< sassc->maxtargets ;i++) {
targ = &sassc->targets[i];
SLIST_FOREACH_SAFE(lun, &targ->luns, lun_link, lun_tmp) {
free(lun, M_MPT2);
@@ -959,9 +967,9 @@ mpssas_action(struct cam_sim *sim, union ccb *ccb)
cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
#endif
cpi->hba_eng_cnt = 0;
- cpi->max_target = sassc->sc->facts->MaxTargets - 1;
+ cpi->max_target = sassc->maxtargets - 1;
cpi->max_lun = 255;
- cpi->initiator_id = sassc->sc->facts->MaxTargets - 1;
+ cpi->initiator_id = sassc->maxtargets - 1;
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
@@ -992,6 +1000,9 @@ mpssas_action(struct cam_sim *sim, union ccb *ccb)
sas = &cts->xport_specific.sas;
scsi = &cts->proto_specific.scsi;
+ KASSERT(cts->ccb_h.target_id < sassc->maxtargets,
+ ("Target %d out of bounds in XPT_GET_TRANS_SETTINGS\n",
+ cts->ccb_h.target_id));
targ = &sassc->targets[cts->ccb_h.target_id];
if (targ->handle == 0x0) {
cts->ccb_h.status = CAM_SEL_TIMEOUT;
@@ -1155,7 +1166,7 @@ mpssas_handle_reinit(struct mps_softc *sc)
* reset, and we have to rediscover all the targets and use the new
* handles.
*/
- for (i = 0; i < sc->facts->MaxTargets; i++) {
+ for (i = 0; i < sc->sassc->maxtargets; i++) {
if (sc->sassc->targets[i].outstanding != 0)
mps_dprint(sc, MPS_INIT, "target %u outstanding %u\n",
i, sc->sassc->targets[i].outstanding);
@@ -1631,6 +1642,9 @@ mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
mtx_assert(&sc->mps_mtx, MA_OWNED);
csio = &ccb->csio;
+ KASSERT(csio->ccb_h.target_id < sassc->maxtargets,
+ ("Target %d out of bounds in XPT_SCSI_IO\n",
+ csio->ccb_h.target_id));
targ = &sassc->targets[csio->ccb_h.target_id];
mps_dprint(sc, MPS_TRACE, "ccb %p target flag %x\n", ccb, targ->flags);
if (targ->handle == 0x0) {
@@ -2929,6 +2943,8 @@ mpssas_action_smpio(struct mpssas_softc *sassc, union ccb *ccb)
/*
* Make sure the target exists.
*/
+ KASSERT(ccb->ccb_h.target_id < sassc->maxtargets,
+ ("Target %d out of bounds in XPT_SMP_IO\n", ccb->ccb_h.target_id));
targ = &sassc->targets[ccb->ccb_h.target_id];
if (targ->handle == 0x0) {
mps_dprint(sc, MPS_ERROR,
@@ -3063,6 +3079,9 @@ mpssas_action_resetdev(struct mpssas_softc *sassc, union ccb *ccb)
MPS_FUNCTRACE(sassc->sc);
mtx_assert(&sassc->sc->mps_mtx, MA_OWNED);
+ KASSERT(ccb->ccb_h.target_id < sassc->maxtargets,
+ ("Target %d out of bounds in XPT_RESET_DEV\n",
+ ccb->ccb_h.target_id));
sc = sassc->sc;
tm = mps_alloc_command(sc);
if (tm == NULL) {
@@ -3191,6 +3210,9 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
/*
* We should have a handle for this, but check to make sure.
*/
+ KASSERT(xpt_path_target_id(path) < sassc->maxtargets,
+ ("Target %d out of bounds in mpssas_async\n",
+ xpt_path_target_id(path)));
target = &sassc->targets[xpt_path_target_id(path)];
if (target->handle == 0)
break;
@@ -3278,6 +3300,9 @@ mpssas_check_eedp(struct mps_softc *sc, struct cam_path *path,
targetid = xpt_path_target_id(path);
lunid = xpt_path_lun_id(path);
+ KASSERT(targetid < sassc->maxtargets,
+ ("Target %d out of bounds in mpssas_check_eedp\n",
+ targetid));
target = &sassc->targets[targetid];
if (target->handle == 0x0)
return;
@@ -3413,6 +3438,9 @@ mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
* target.
*/
sassc = (struct mpssas_softc *)done_ccb->ccb_h.ppriv_ptr1;
+ KASSERT(done_ccb->ccb_h.target_id < sassc->maxtargets,
+ ("Target %d out of bounds in mpssas_read_cap_done\n",
+ done_ccb->ccb_h.target_id));
target = &sassc->targets[done_ccb->ccb_h.target_id];
SLIST_FOREACH(lun, &target->luns, lun_link) {
if (lun->lun_id != done_ccb->ccb_h.target_lun)
diff --git a/sys/dev/mps/mps_sas.h b/sys/dev/mps/mps_sas.h
index f6a0820..0c3bb08 100644
--- a/sys/dev/mps/mps_sas.h
+++ b/sys/dev/mps/mps_sas.h
@@ -87,6 +87,7 @@ struct mpssas_softc {
#define MPSSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2)
#define MPSSAS_QUEUE_FROZEN (1 << 3)
#define MPSSAS_SHUTDOWN (1 << 4)
+ u_int maxtargets;
struct mpssas_target *targets;
struct cam_devq *devq;
struct cam_sim *sim;
OpenPOWER on IntegriCloud