Print this page
NEX-3672 IDM module panics target when PDU has AHS length between 17 and 49
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/idm/idm_so.c
          +++ new/usr/src/uts/common/io/idm/idm_so.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /*
  26   26   * Copyright (c) 2013 by Delphix. All rights reserved.
       27 + * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  27   28   * Copyright (c) 2017, Joyent, Inc.  All rights reserved.
  28   29   */
  29   30  
  30   31  #include <sys/conf.h>
  31   32  #include <sys/stat.h>
  32   33  #include <sys/file.h>
  33   34  #include <sys/ddi.h>
  34   35  #include <sys/sunddi.h>
  35   36  #include <sys/modctl.h>
  36   37  #include <sys/priv.h>
↓ open down ↓ 815 lines elided ↑ open up ↑
 852  853           */
 853  854          bhs = pdu->isp_hdr;
 854  855          rc = idm_sorecv(so_conn->ic_so, pdu->isp_hdr, sizeof (iscsi_hdr_t));
 855  856          if (rc != IDM_STATUS_SUCCESS) {
 856  857                  return (IDM_STATUS_FAIL);
 857  858          }
 858  859  
 859  860          /*
 860  861           * Check actual AHS length against the amount available in the buffer
 861  862           */
      863 +        if ((IDM_PDU_OPCODE(pdu) != ISCSI_OP_SCSI_CMD) &&
      864 +            (bhs->hlength != 0)) {
      865 +                /* ---- hlength is only only valid for SCSI Request ---- */
      866 +                return (IDM_STATUS_FAIL);
      867 +        }
 862  868          pdu->isp_hdrlen = sizeof (iscsi_hdr_t) +
 863  869              (bhs->hlength * sizeof (uint32_t));
 864  870          pdu->isp_datalen = n2h24(bhs->dlength);
 865  871  
 866  872          if (!idm_dataseglenokay(ic, pdu)) {
 867  873                  IDM_CONN_LOG(CE_WARN,
 868  874                      "idm_sorecvhdr: invalid data segment length");
 869  875                  return (IDM_STATUS_FAIL);
 870  876          }
 871      -        if (bhs->hlength > IDM_SORX_CACHE_AHSLEN) {
      877 +        if (bhs->hlength > IDM_SORX_WIRE_AHSLEN) {
 872  878                  /* Allocate a new header segment and change the callback */
 873  879                  new_hdr = kmem_alloc(pdu->isp_hdrlen, KM_SLEEP);
 874  880                  bcopy(pdu->isp_hdr, new_hdr, sizeof (iscsi_hdr_t));
 875  881                  pdu->isp_hdr = new_hdr;
 876  882                  pdu->isp_flags |= IDM_PDU_ADDL_HDR;
 877  883  
 878  884                  /*
 879  885                   * This callback will restore the expected values after
 880  886                   * the RX PDU has been processed.
 881  887                   */
↓ open down ↓ 2368 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX