aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mpr
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2018-12-21 20:29:16 +0000
committerConrad Meyer <cem@FreeBSD.org>2018-12-21 20:29:16 +0000
commit8277ce2b78a257450674e623e41f4692ab8c7633 (patch)
treef40e3a616c3cc2710d9126f647cdbc745e0d97d3 /sys/dev/mpr
parent8ec22c4d65acc981a0cee408d02f70273255ac5a (diff)
downloadsrc-8277ce2b78a257450674e623e41f4692ab8c7633.tar.gz
src-8277ce2b78a257450674e623e41f4692ab8c7633.zip
mps(4), mpr(4): Fix lifetime of command buffer for mp?sas_get_sata_identify
In the event that the ID command timed out, mps(4)/mpr(4) did not free the command until it could be cancelled. However, it freed the associated buffer (cm_data). Fix the lifetime issue by freeing the associated buffer only after Abort Task or controller reset. Reviewed by: scottl Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D18612
Notes
Notes: svn path=/head/; revision=342354
Diffstat (limited to 'sys/dev/mpr')
-rw-r--r--sys/dev/mpr/mpr_sas.c6
-rw-r--r--sys/dev/mpr/mpr_sas_lsi.c12
2 files changed, 12 insertions, 6 deletions
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 04a2d3f9594a..93c27803867a 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -1169,6 +1169,12 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
cm->cm_reply = NULL;
completed = 0;
+ if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
+ MPASS(cm->cm_data);
+ free(cm->cm_data, M_MPR);
+ cm->cm_data = NULL;
+ }
+
if (cm->cm_flags & MPR_CM_FLAGS_POLLED)
cm->cm_flags |= MPR_CM_FLAGS_COMPLETE;
diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c
index fd74590baff4..d308ffff8b4c 100644
--- a/sys/dev/mpr/mpr_sas_lsi.c
+++ b/sys/dev/mpr/mpr_sas_lsi.c
@@ -1026,6 +1026,7 @@ out:
for (i = 1; i < sc->num_reqs; i++) {
cm = &sc->commands[i];
if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
+ free(cm->cm_data, M_MPR);
mpr_free_command(sc, cm);
}
}
@@ -1208,15 +1209,14 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
out:
/*
* If the SATA_ID_TIMEOUT flag has been set for this command, don't free
- * it. The command will be freed after sending a target reset TM. If
- * the command did timeout, use EWOULDBLOCK.
+ * it. The command and buffer will be freed after sending an Abort
+ * Task TM. If the command did timeout, use EWOULDBLOCK.
*/
- if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
+ if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0) {
mpr_free_command(sc, cm);
- else if (error == 0)
+ free(buffer, M_MPR);
+ } else if (error == 0)
error = EWOULDBLOCK;
- cm->cm_data = NULL;
- free(buffer, M_MPR);
return (error);
}