Author: trasz
Date: Tue Sep 24 13:46:13 2013
New Revision: 255848
URL: http://svnweb.freebsd.org/changeset/base/255848

Log:
  Properly ignore PDUs with CmdSN outside of allowed range.
  
  Approved by:  re (glebius)
  Sponsored by: FreeBSD Foundation

Modified:
  head/sys/cam/ctl/ctl_frontend_iscsi.c

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.c       Tue Sep 24 12:50:04 2013        
(r255847)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.c       Tue Sep 24 13:46:13 2013        
(r255848)
@@ -147,7 +147,7 @@ static int  cfiscsi_devid(struct ctl_scsi
 static void    cfiscsi_datamove(union ctl_io *io);
 static void    cfiscsi_done(union ctl_io *io);
 static uint32_t        cfiscsi_map_lun(void *arg, uint32_t lun);
-static void    cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request);
+static bool    cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request);
 static void    cfiscsi_pdu_handle_nop_out(struct icl_pdu *request);
 static void    cfiscsi_pdu_handle_scsi_command(struct icl_pdu *request);
 static void    cfiscsi_pdu_handle_task_request(struct icl_pdu *request);
@@ -182,7 +182,7 @@ cfiscsi_pdu_new_response(struct icl_pdu 
        return (icl_pdu_new_bhs(request->ip_conn, flags));
 }
 
-static void
+static bool
 cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request)
 {
        const struct iscsi_bhs_scsi_command *bhssc;
@@ -206,7 +206,7 @@ cfiscsi_pdu_update_cmdsn(const struct ic
         */
        if ((request->ip_bhs->bhs_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) ==
            ISCSI_BHS_OPCODE_SCSI_DATA_OUT)
-               return;
+               return (false);
 
        /*
         * We're only using fields common for all the request
@@ -226,38 +226,39 @@ cfiscsi_pdu_update_cmdsn(const struct ic
 #endif
 
        /*
-        * XXX: The target MUST silently ignore any non-immediate command
-        *      outside of this range or non-immediate duplicates within
-        *      the range.
+        * The target MUST silently ignore any non-immediate command outside
+        * of this range.
+        *
+        * XXX: ... or non-immediate duplicates within the range.
         */
-       if (cmdsn != cs->cs_cmdsn) {
+       if (cmdsn < cs->cs_cmdsn || cmdsn > cs->cs_cmdsn + maxcmdsn_delta) {
+               CFISCSI_SESSION_UNLOCK(cs);
                CFISCSI_SESSION_WARN(cs, "received PDU with CmdSN %d, "
                    "while expected CmdSN was %d", cmdsn, cs->cs_cmdsn);
-               cs->cs_cmdsn = cmdsn + 1;
-               CFISCSI_SESSION_UNLOCK(cs);
-               return;
+               return (true);
        }
 
-       /*
-        * XXX: The CmdSN of the rejected command PDU (if it is a non-immediate
-        *      command) MUST NOT be considered received by the target
-        *      (i.e., a command sequence gap must be assumed for the CmdSN)
-        */
-
        if ((request->ip_bhs->bhs_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0)
                cs->cs_cmdsn++;
 
        CFISCSI_SESSION_UNLOCK(cs);
+
+       return (false);
 }
 
 static void
 cfiscsi_pdu_handle(struct icl_pdu *request)
 {
        struct cfiscsi_session *cs;
+       bool ignore;
 
        cs = PDU_SESSION(request);
 
-       cfiscsi_pdu_update_cmdsn(request);
+       ignore = cfiscsi_pdu_update_cmdsn(request);
+       if (ignore) {
+               icl_pdu_free(request);
+               return;
+       }
 
        /*
         * Handle the PDU; this includes e.g. receiving the remaining
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to