Author: cem
Date: Fri Dec 21 20:29:16 2018
New Revision: 342354
URL: https://svnweb.freebsd.org/changeset/base/342354

Log:
  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

Modified:
  head/sys/dev/mpr/mpr_sas.c
  head/sys/dev/mpr/mpr_sas_lsi.c
  head/sys/dev/mps/mps_sas.c
  head/sys/dev/mps/mps_sas_lsi.c

Modified: head/sys/dev/mpr/mpr_sas.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas.c  Fri Dec 21 20:12:43 2018        (r342353)
+++ head/sys/dev/mpr/mpr_sas.c  Fri Dec 21 20:29:16 2018        (r342354)
@@ -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;
 

Modified: head/sys/dev/mpr/mpr_sas_lsi.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas_lsi.c      Fri Dec 21 20:12:43 2018        
(r342353)
+++ head/sys/dev/mpr/mpr_sas_lsi.c      Fri Dec 21 20:29:16 2018        
(r342354)
@@ -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 han
 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);
 }
 

Modified: head/sys/dev/mps/mps_sas.c
==============================================================================
--- head/sys/dev/mps/mps_sas.c  Fri Dec 21 20:12:43 2018        (r342353)
+++ head/sys/dev/mps/mps_sas.c  Fri Dec 21 20:29:16 2018        (r342354)
@@ -1108,6 +1108,12 @@ mpssas_complete_all_commands(struct mps_softc *sc)
                cm->cm_reply = NULL;
                completed = 0;
 
+               if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
+                       MPASS(cm->cm_data);
+                       free(cm->cm_data, M_MPT2);
+                       cm->cm_data = NULL;
+               }
+
                if (cm->cm_flags & MPS_CM_FLAGS_POLLED)
                        cm->cm_flags |= MPS_CM_FLAGS_COMPLETE;
 

Modified: head/sys/dev/mps/mps_sas_lsi.c
==============================================================================
--- head/sys/dev/mps/mps_sas_lsi.c      Fri Dec 21 20:12:43 2018        
(r342353)
+++ head/sys/dev/mps/mps_sas_lsi.c      Fri Dec 21 20:29:16 2018        
(r342354)
@@ -818,6 +818,7 @@ out:
        for (i = 1; i < sc->num_reqs; i++) {
                cm = &sc->commands[i];
                if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
+                       free(cm->cm_data, M_MPT2);
                        mps_free_command(sc, cm);
                }
        }
@@ -1000,15 +1001,15 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 han
 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 != NULL)
-        && (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
+           && (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0) {
                mps_free_command(sc, cm);
-       else if (error == 0)
+               free(buffer, M_MPT2);
+       } else if (error == 0)
                error = EWOULDBLOCK;
-       free(buffer, M_MPT2);
        return (error);
 }
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to