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