Print this page
1918 stack overflow from mac_promisc_dispatch()
        
*** 18,27 ****
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  * Copyright 2011, Nexenta Systems, Inc. All rights reserved.
   */
  
  /*
   * Data-Link Driver
   */
*** 571,581 ****
  proto_promiscon_req(dld_str_t *dsp, mblk_t *mp)
  {
          dl_promiscon_req_t *dlp = (dl_promiscon_req_t *)mp->b_rptr;
          int             err = 0;
          t_uscalar_t     dl_err;
!         uint32_t        promisc_saved;
          queue_t         *q = dsp->ds_wq;
          mac_perim_handle_t      mph;
  
          if (MBLKL(mp) < sizeof (dl_promiscon_req_t)) {
                  dl_err = DL_BADPRIM;
--- 572,582 ----
  proto_promiscon_req(dld_str_t *dsp, mblk_t *mp)
  {
          dl_promiscon_req_t *dlp = (dl_promiscon_req_t *)mp->b_rptr;
          int             err = 0;
          t_uscalar_t     dl_err;
!         uint32_t        new_flags, promisc_saved;
          queue_t         *q = dsp->ds_wq;
          mac_perim_handle_t      mph;
  
          if (MBLKL(mp) < sizeof (dl_promiscon_req_t)) {
                  dl_err = DL_BADPRIM;
*** 586,626 ****
              DL_ACK_PENDING(dsp->ds_dlstate)) {
                  dl_err = DL_OUTSTATE;
                  goto failed;
          }
  
!         promisc_saved = dsp->ds_promisc;
          switch (dlp->dl_level) {
          case DL_PROMISC_SAP:
!                 dsp->ds_promisc |= DLS_PROMISC_SAP;
                  break;
  
          case DL_PROMISC_MULTI:
!                 dsp->ds_promisc |= DLS_PROMISC_MULTI;
                  break;
  
          case DL_PROMISC_PHYS:
!                 dsp->ds_promisc |= DLS_PROMISC_PHYS;
                  break;
  
          default:
                  dl_err = DL_NOTSUPPORTED;
                  goto failed;
          }
  
-         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
- 
          if ((promisc_saved == 0) && (err = dls_active_set(dsp)) != 0) {
!                 dsp->ds_promisc = promisc_saved;
                  dl_err = DL_SYSERR;
                  goto failed2;
          }
  
          /*
           * Adjust channel promiscuity.
           */
!         err = dls_promisc(dsp, promisc_saved);
  
          if (err != 0) {
                  dl_err = DL_SYSERR;
                  dsp->ds_promisc = promisc_saved;
                  if (promisc_saved == 0)
--- 587,627 ----
              DL_ACK_PENDING(dsp->ds_dlstate)) {
                  dl_err = DL_OUTSTATE;
                  goto failed;
          }
  
!         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
! 
!         new_flags = promisc_saved = dsp->ds_promisc;
          switch (dlp->dl_level) {
          case DL_PROMISC_SAP:
!                 new_flags |= DLS_PROMISC_SAP;
                  break;
  
          case DL_PROMISC_MULTI:
!                 new_flags |= DLS_PROMISC_MULTI;
                  break;
  
          case DL_PROMISC_PHYS:
!                 new_flags |= DLS_PROMISC_PHYS;
                  break;
  
          default:
                  dl_err = DL_NOTSUPPORTED;
                  goto failed;
          }
  
          if ((promisc_saved == 0) && (err = dls_active_set(dsp)) != 0) {
!                 ASSERT(dsp->ds_promisc == promisc_saved);
                  dl_err = DL_SYSERR;
                  goto failed2;
          }
  
          /*
           * Adjust channel promiscuity.
           */
!         err = dls_promisc(dsp, new_flags);
  
          if (err != 0) {
                  dl_err = DL_SYSERR;
                  dsp->ds_promisc = promisc_saved;
                  if (promisc_saved == 0)
*** 646,656 ****
  proto_promiscoff_req(dld_str_t *dsp, mblk_t *mp)
  {
          dl_promiscoff_req_t *dlp = (dl_promiscoff_req_t *)mp->b_rptr;
          int             err = 0;
          t_uscalar_t     dl_err;
!         uint32_t        promisc_saved;
          queue_t         *q = dsp->ds_wq;
          mac_perim_handle_t      mph;
  
          if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
                  dl_err = DL_BADPRIM;
--- 647,657 ----
  proto_promiscoff_req(dld_str_t *dsp, mblk_t *mp)
  {
          dl_promiscoff_req_t *dlp = (dl_promiscoff_req_t *)mp->b_rptr;
          int             err = 0;
          t_uscalar_t     dl_err;
!         uint32_t        new_flags;
          queue_t         *q = dsp->ds_wq;
          mac_perim_handle_t      mph;
  
          if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
                  dl_err = DL_BADPRIM;
*** 661,713 ****
              DL_ACK_PENDING(dsp->ds_dlstate)) {
                  dl_err = DL_OUTSTATE;
                  goto failed;
          }
  
!         promisc_saved = dsp->ds_promisc;
          switch (dlp->dl_level) {
          case DL_PROMISC_SAP:
                  if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
                          dl_err = DL_NOTENAB;
                          goto failed;
                  }
!                 dsp->ds_promisc &= ~DLS_PROMISC_SAP;
                  break;
  
          case DL_PROMISC_MULTI:
                  if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
                          dl_err = DL_NOTENAB;
                          goto failed;
                  }
!                 dsp->ds_promisc &= ~DLS_PROMISC_MULTI;
                  break;
  
          case DL_PROMISC_PHYS:
                  if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
                          dl_err = DL_NOTENAB;
                          goto failed;
                  }
!                 dsp->ds_promisc &= ~DLS_PROMISC_PHYS;
                  break;
  
          default:
                  dl_err = DL_NOTSUPPORTED;
                  goto failed;
          }
  
-         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
          /*
           * Adjust channel promiscuity.
           */
!         err = dls_promisc(dsp, promisc_saved);
  
          if (err != 0) {
                  mac_perim_exit(mph);
                  dl_err = DL_SYSERR;
                  goto failed;
          }
  
          if (dsp->ds_promisc == 0)
                  dls_active_clear(dsp, B_FALSE);
  
          mac_perim_exit(mph);
  
--- 662,716 ----
              DL_ACK_PENDING(dsp->ds_dlstate)) {
                  dl_err = DL_OUTSTATE;
                  goto failed;
          }
  
!         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
! 
!         new_flags = dsp->ds_promisc;
          switch (dlp->dl_level) {
          case DL_PROMISC_SAP:
                  if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
                          dl_err = DL_NOTENAB;
                          goto failed;
                  }
!                 new_flags &= ~DLS_PROMISC_SAP;
                  break;
  
          case DL_PROMISC_MULTI:
                  if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
                          dl_err = DL_NOTENAB;
                          goto failed;
                  }
!                 new_flags &= ~DLS_PROMISC_MULTI;
                  break;
  
          case DL_PROMISC_PHYS:
                  if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
                          dl_err = DL_NOTENAB;
                          goto failed;
                  }
!                 new_flags &= ~DLS_PROMISC_PHYS;
                  break;
  
          default:
                  dl_err = DL_NOTSUPPORTED;
                  goto failed;
          }
  
          /*
           * Adjust channel promiscuity.
           */
!         err = dls_promisc(dsp, new_flags);
  
          if (err != 0) {
                  mac_perim_exit(mph);
                  dl_err = DL_SYSERR;
                  goto failed;
          }
  
+         ASSERT(dsp->ds_promisc == new_flags);
          if (dsp->ds_promisc == 0)
                  dls_active_clear(dsp, B_FALSE);
  
          mac_perim_exit(mph);