Print this page
653 incorrect handling in iscsit of duplicate PDUs with cmdsn > expsn
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Gary Mills <gary_mills@fastmail.fm>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/comstar/port/iscsit/iscsit.c
          +++ new/usr/src/uts/common/io/comstar/port/iscsit/iscsit.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + *
       24 + * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  23   25   */
  24      -/*
  25      - * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  26      - */
  27   26  
  28   27  #include <sys/cpuvar.h>
  29   28  #include <sys/types.h>
  30   29  #include <sys/conf.h>
  31   30  #include <sys/stat.h>
  32   31  #include <sys/file.h>
  33   32  #include <sys/ddi.h>
  34   33  #include <sys/sunddi.h>
  35   34  #include <sys/modctl.h>
  36   35  #include <sys/sysmacros.h>
↓ open down ↓ 3117 lines elided ↑ open up ↑
3154 3153          mutex_enter(&ict->ict_mutex);
3155 3154          if (ict->ict_lost) {
3156 3155                  mutex_exit(&ict->ict_mutex);
3157 3156                  idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL);
3158 3157                  return;
3159 3158          }
3160 3159          iscsit_conn_dispatch_hold(ict);
3161 3160          mutex_exit(&ict->ict_mutex);
3162 3161  
3163 3162          index = ntohl(cmdsn) % ISCSIT_RXPDU_QUEUE_LEN;
3164      -        ASSERT(cbuf->cb_buffer[index] == NULL);
3165      -        cbuf->cb_buffer[index] = rx_pdu;
3166      -        cbuf->cb_num_elems++;
     3163 +        /*
     3164 +         * In the normal case, assuming that the Initiator is not
     3165 +         * buggy and that we don't have packet duplication occuring,
     3166 +         * the entry in the array will be NULL.  However, we may have
     3167 +         * received a duplicate PDU with cmdsn > expsn , and in that
     3168 +         * case we just ignore this PDU -- the previously received one
     3169 +         * remains queued for processing.  We need to be careful not
     3170 +         * to leak this one however.
     3171 +         */
     3172 +        if (cbuf->cb_buffer[index] != NULL) {
     3173 +                idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL);
     3174 +        } else {
     3175 +                cbuf->cb_buffer[index] = rx_pdu;
     3176 +                cbuf->cb_num_elems++;
     3177 +        }
3167 3178  }
3168 3179  
3169 3180  static idm_pdu_t *
3170 3181  iscsit_remove_pdu_from_queue(iscsit_sess_t *ist, uint32_t cmdsn)
3171 3182  {
3172 3183          iscsit_cbuf_t   *cbuf   = ist->ist_rxpdu_queue;
3173 3184          idm_pdu_t       *pdu    = NULL;
3174 3185          uint32_t        index;
3175 3186  
3176 3187          ASSERT(MUTEX_HELD(&ist->ist_sn_mutex));
↓ open down ↓ 232 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX