Print this page
1918 stack overflow from mac_promisc_dispatch()

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/dld/dld_proto.c
          +++ new/usr/src/uts/common/io/dld/dld_proto.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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) 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2011, Nexenta Systems, Inc. All rights reserved.
  23   24   */
  24   25  
  25   26  /*
  26   27   * Data-Link Driver
  27   28   */
  28   29  #include <sys/sysmacros.h>
  29   30  #include <sys/strsubr.h>
  30   31  #include <sys/strsun.h>
  31   32  #include <sys/vlan.h>
  32   33  #include <sys/dld_impl.h>
↓ open down ↓ 533 lines elided ↑ open up ↑
 566  567  
 567  568  /*
 568  569   * DL_PROMISCON_REQ
 569  570   */
 570  571  static void
 571  572  proto_promiscon_req(dld_str_t *dsp, mblk_t *mp)
 572  573  {
 573  574          dl_promiscon_req_t *dlp = (dl_promiscon_req_t *)mp->b_rptr;
 574  575          int             err = 0;
 575  576          t_uscalar_t     dl_err;
 576      -        uint32_t        promisc_saved;
      577 +        uint32_t        new_flags, promisc_saved;
 577  578          queue_t         *q = dsp->ds_wq;
 578  579          mac_perim_handle_t      mph;
 579  580  
 580  581          if (MBLKL(mp) < sizeof (dl_promiscon_req_t)) {
 581  582                  dl_err = DL_BADPRIM;
 582  583                  goto failed;
 583  584          }
 584  585  
 585  586          if (dsp->ds_dlstate == DL_UNATTACHED ||
 586  587              DL_ACK_PENDING(dsp->ds_dlstate)) {
 587  588                  dl_err = DL_OUTSTATE;
 588  589                  goto failed;
 589  590          }
 590  591  
 591      -        promisc_saved = dsp->ds_promisc;
      592 +        mac_perim_enter_by_mh(dsp->ds_mh, &mph);
      593 +
      594 +        new_flags = promisc_saved = dsp->ds_promisc;
 592  595          switch (dlp->dl_level) {
 593  596          case DL_PROMISC_SAP:
 594      -                dsp->ds_promisc |= DLS_PROMISC_SAP;
      597 +                new_flags |= DLS_PROMISC_SAP;
 595  598                  break;
 596  599  
 597  600          case DL_PROMISC_MULTI:
 598      -                dsp->ds_promisc |= DLS_PROMISC_MULTI;
      601 +                new_flags |= DLS_PROMISC_MULTI;
 599  602                  break;
 600  603  
 601  604          case DL_PROMISC_PHYS:
 602      -                dsp->ds_promisc |= DLS_PROMISC_PHYS;
      605 +                new_flags |= DLS_PROMISC_PHYS;
 603  606                  break;
 604  607  
 605  608          default:
 606  609                  dl_err = DL_NOTSUPPORTED;
 607  610                  goto failed;
 608  611          }
 609  612  
 610      -        mac_perim_enter_by_mh(dsp->ds_mh, &mph);
 611      -
 612  613          if ((promisc_saved == 0) && (err = dls_active_set(dsp)) != 0) {
 613      -                dsp->ds_promisc = promisc_saved;
      614 +                ASSERT(dsp->ds_promisc == promisc_saved);
 614  615                  dl_err = DL_SYSERR;
 615  616                  goto failed2;
 616  617          }
 617  618  
 618  619          /*
 619  620           * Adjust channel promiscuity.
 620  621           */
 621      -        err = dls_promisc(dsp, promisc_saved);
      622 +        err = dls_promisc(dsp, new_flags);
 622  623  
 623  624          if (err != 0) {
 624  625                  dl_err = DL_SYSERR;
 625  626                  dsp->ds_promisc = promisc_saved;
 626  627                  if (promisc_saved == 0)
 627  628                          dls_active_clear(dsp, B_FALSE);
 628  629                  goto failed2;
 629  630          }
 630  631  
 631  632          mac_perim_exit(mph);
↓ open down ↓ 9 lines elided ↑ open up ↑
 641  642  
 642  643  /*
 643  644   * DL_PROMISCOFF_REQ
 644  645   */
 645  646  static void
 646  647  proto_promiscoff_req(dld_str_t *dsp, mblk_t *mp)
 647  648  {
 648  649          dl_promiscoff_req_t *dlp = (dl_promiscoff_req_t *)mp->b_rptr;
 649  650          int             err = 0;
 650  651          t_uscalar_t     dl_err;
 651      -        uint32_t        promisc_saved;
      652 +        uint32_t        new_flags;
 652  653          queue_t         *q = dsp->ds_wq;
 653  654          mac_perim_handle_t      mph;
 654  655  
 655  656          if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
 656  657                  dl_err = DL_BADPRIM;
 657  658                  goto failed;
 658  659          }
 659  660  
 660  661          if (dsp->ds_dlstate == DL_UNATTACHED ||
 661  662              DL_ACK_PENDING(dsp->ds_dlstate)) {
 662  663                  dl_err = DL_OUTSTATE;
 663  664                  goto failed;
 664  665          }
 665  666  
 666      -        promisc_saved = dsp->ds_promisc;
      667 +        mac_perim_enter_by_mh(dsp->ds_mh, &mph);
      668 +
      669 +        new_flags = dsp->ds_promisc;
 667  670          switch (dlp->dl_level) {
 668  671          case DL_PROMISC_SAP:
 669  672                  if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
 670  673                          dl_err = DL_NOTENAB;
 671  674                          goto failed;
 672  675                  }
 673      -                dsp->ds_promisc &= ~DLS_PROMISC_SAP;
      676 +                new_flags &= ~DLS_PROMISC_SAP;
 674  677                  break;
 675  678  
 676  679          case DL_PROMISC_MULTI:
 677  680                  if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
 678  681                          dl_err = DL_NOTENAB;
 679  682                          goto failed;
 680  683                  }
 681      -                dsp->ds_promisc &= ~DLS_PROMISC_MULTI;
      684 +                new_flags &= ~DLS_PROMISC_MULTI;
 682  685                  break;
 683  686  
 684  687          case DL_PROMISC_PHYS:
 685  688                  if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
 686  689                          dl_err = DL_NOTENAB;
 687  690                          goto failed;
 688  691                  }
 689      -                dsp->ds_promisc &= ~DLS_PROMISC_PHYS;
      692 +                new_flags &= ~DLS_PROMISC_PHYS;
 690  693                  break;
 691  694  
 692  695          default:
 693  696                  dl_err = DL_NOTSUPPORTED;
 694  697                  goto failed;
 695  698          }
 696  699  
 697      -        mac_perim_enter_by_mh(dsp->ds_mh, &mph);
 698  700          /*
 699  701           * Adjust channel promiscuity.
 700  702           */
 701      -        err = dls_promisc(dsp, promisc_saved);
      703 +        err = dls_promisc(dsp, new_flags);
 702  704  
 703  705          if (err != 0) {
 704  706                  mac_perim_exit(mph);
 705  707                  dl_err = DL_SYSERR;
 706  708                  goto failed;
 707  709          }
 708  710  
      711 +        ASSERT(dsp->ds_promisc == new_flags);
 709  712          if (dsp->ds_promisc == 0)
 710  713                  dls_active_clear(dsp, B_FALSE);
 711  714  
 712  715          mac_perim_exit(mph);
 713  716  
 714  717          dlokack(q, mp, DL_PROMISCOFF_REQ);
 715  718          return;
 716  719  failed:
 717  720          dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err);
 718  721  }
↓ open down ↓ 1000 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX