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"