Print this page
12976 system panics with error in IP module
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Reviewed by: Paul Winder <p.winder@me.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/ipclassifier.c
          +++ new/usr/src/uts/common/inet/ip/ipclassifier.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
       24 + * Copyright 2020 Joyent, Inc.
  24   25   */
  25   26  
  26   27  /*
  27   28   * IP PACKET CLASSIFIER
  28   29   *
  29   30   * The IP packet classifier provides mapping between IP packets and persistent
  30   31   * connection state for connection-oriented protocols. It also provides
  31   32   * interface for managing connection states.
  32   33   *
  33   34   * The connection state is kept in conn_t data structure and contains, among
↓ open down ↓ 2704 lines elided ↑ open up ↑
2738 2739           * The callers of this function have a reference on connp itself
2739 2740           * so, as long as it is not closing, it's safe to continue.
2740 2741           */
2741 2742          mutex_enter(&connp->conn_lock);
2742 2743  
2743 2744          if ((connp->conn_state_flags & CONN_CLOSING)) {
2744 2745                  mutex_exit(&connp->conn_lock);
2745 2746                  return (NULL);
2746 2747          }
2747 2748  
2748      -        mutex_exit(&connp->conn_lock);
     2749 +        /*
     2750 +         * Continue to hold conn_lock because we don't want to race with an
     2751 +         * in-progress close, which will have set-to-NULL (and destroyed
     2752 +         * upper_handle, aka sonode (and vnode)) BEFORE setting CONN_CLOSING.
     2753 +         */
2749 2754  
2750 2755          if (connp->conn_upper_handle != NULL) {
2751 2756                  vn = (*connp->conn_upcalls->su_get_vnode)
2752 2757                      (connp->conn_upper_handle);
2753 2758          } else if (!IPCL_IS_NONSTR(connp) && connp->conn_rq != NULL) {
2754 2759                  vn = STREAM(connp->conn_rq)->sd_pvnode;
2755 2760                  if (vn != NULL)
2756 2761                          VN_HOLD(vn);
2757 2762                  flags |= MIB2_SOCKINFO_STREAM;
2758 2763          }
2759 2764  
     2765 +        mutex_exit(&connp->conn_lock);
     2766 +
2760 2767          if (vn == NULL || VOP_GETATTR(vn, &attr, 0, CRED(), NULL) != 0) {
2761 2768                  if (vn != NULL)
2762 2769                          VN_RELE(vn);
2763 2770                  return (NULL);
2764 2771          }
2765 2772  
2766 2773          VN_RELE(vn);
2767 2774  
2768 2775          bzero(sie, sizeof (*sie));
2769 2776  
2770 2777          sie->sie_flags = flags;
2771 2778          sie->sie_inode = attr.va_nodeid;
2772 2779          sie->sie_dev = attr.va_rdev;
2773 2780  
2774 2781          return (sie);
2775 2782  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX