diff options
author | Conrad Meyer <cem@FreeBSD.org> | 2018-12-21 20:29:16 +0000 |
---|---|---|
committer | Conrad Meyer <cem@FreeBSD.org> | 2018-12-21 20:29:16 +0000 |
commit | 8277ce2b78a257450674e623e41f4692ab8c7633 (patch) | |
tree | f40e3a616c3cc2710d9126f647cdbc745e0d97d3 /sys/dev/mpr | |
parent | 8ec22c4d65acc981a0cee408d02f70273255ac5a (diff) | |
download | src-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.c | 6 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_sas_lsi.c | 12 |
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); } |