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);