Print this page
NEX-19225 SMB client 2.1 hits redzone panic
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbclnt/netsmb/subr_mchain.c
          +++ new/usr/src/uts/common/fs/smbclnt/netsmb/subr_mchain.c
↓ open down ↓ 25 lines elided ↑ open up ↑
  26   26   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27   27   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28   28   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29   29   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30   30   * SUCH DAMAGE.
  31   31   *
  32   32   * $FreeBSD: src/sys/kern/subr_mchain.c,v 1.1 2001/02/24 15:44:29 bp Exp $
  33   33   */
  34   34  
  35   35  /*
  36      - * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  37   36   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  38   37   * Use is subject to license terms.
       38 + *
       39 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  39   40   */
  40   41  
  41   42  #include <sys/param.h>
  42   43  #include <sys/systm.h>
  43   44  #include <sys/errno.h>
  44   45  #include <sys/uio.h>
  45   46  #include <sys/types.h>
  46   47  #include <sys/stream.h>
  47   48  #include <sys/strsun.h>
  48   49  #include <sys/strsubr.h>
↓ open down ↓ 57 lines elided ↑ open up ↑
 106  107   * There's more to MLEN than you might think.
 107  108   * Some ethernet drivers may send each mblk as a
 108  109   * separate frame, so we want MLEN at least 1K.
 109  110   * We could have used 1K here, but that might
 110  111   * hurt transports that support larger frames.
 111  112   * 4K fits nicely in 3 Ethernet frames (3 * 1500)
 112  113   * leaving about 500 bytes for protocol headers.
 113  114   */
 114  115  #define MLEN    4096
 115  116  
      117 +#if (MLEN < SMB2_HDRLEN)
      118 +#error "MLEN can't fit a contiguous SMB2 header"
      119 +#endif
 116  120  
 117  121  /*
 118  122   * Some UIO routines.
 119  123   * Taken from Darwin Sourcecs.
 120  124   */
 121  125  
 122  126  /*
 123  127   * uio_isuserspace - non zero value if the address space
 124  128   * flag is for a user address space (could be 32 or 64 bit).
 125  129   */
↓ open down ↓ 287 lines elided ↑ open up ↑
 413  417  
 414  418          dst = (uintptr_t)mbp->mb_cur->b_wptr;
 415  419          /* only add padding if address is odd */
 416  420          if (dst & 1) {
 417  421                  MB_PUT_INLINE(mbp, &v, sizeof (v));
 418  422          }
 419  423  
 420  424          return (0);
 421  425  }
 422  426  
      427 +/*
      428 + * Adds padding to 8 byte boundary
      429 + */
 423  430  int
      431 +mb_put_align8(struct mbchain *mbp)
      432 +{
      433 +        static const char zeros[8] = { 0 };
      434 +        int pad_len = 0;
      435 +
      436 +        if ((mbp->mb_count % 8) != 0) {
      437 +                pad_len = 8 - (mbp->mb_count % 8);
      438 +                MB_PUT_INLINE(mbp, zeros, pad_len);
      439 +        }
      440 +        return (0);
      441 +}
      442 +
      443 +int
 424  444  mb_put_uint8(struct mbchain *mbp, u_int8_t x)
 425  445  {
 426  446          u_int8_t v = x;
 427  447          MB_PUT_INLINE(mbp, &v, sizeof (v));
 428  448  }
 429  449  
 430  450  int
 431  451  mb_put_uint16be(struct mbchain *mbp, u_int16_t x)
 432  452  {
 433  453          u_int16_t v = htobes(x);
↓ open down ↓ 96 lines elided ↑ open up ↑
 530  550                  mleft -= cplen;
 531  551                  m->b_wptr += cplen;
 532  552                  mbp->mb_count += cplen;
 533  553          }
 534  554          mbp->mb_cur = m;
 535  555          return (0);
 536  556  }
 537  557  
 538  558  /*
 539  559   * Append an mblk to the chain.
      560 + * Note: The mblk_t *m is consumed.
 540  561   */
 541  562  int
 542  563  mb_put_mbuf(struct mbchain *mbp, mblk_t *m)
 543  564  {
 544  565          mblk_t *nm, *tail_mb;
 545  566          size_t size;
 546  567  
 547  568          /* See: linkb(9f) */
 548  569          tail_mb = mbp->mb_cur;
 549  570          while (tail_mb->b_cont != NULL)
↓ open down ↓ 19 lines elided ↑ open up ↑
 569  590                  mbp->mb_count += size;
 570  591                  nm = unlinkb(m);
 571  592                  freeb(m);
 572  593                  m = nm;
 573  594          }
 574  595  
 575  596          return (0);
 576  597  }
 577  598  
 578  599  /*
      600 + * Put an mbchain into another mbchain
      601 + * Leave sub_mbp untouched.
      602 + */
      603 +int
      604 +mb_put_mbchain(struct mbchain *mbp, struct mbchain *sub_mbp)
      605 +{
      606 +        mblk_t *m;
      607 +
      608 +        if (sub_mbp == NULL)
      609 +                return (0);
      610 +
      611 +        m = sub_mbp->mb_top;
      612 +        if (m == NULL)
      613 +                return (0);
      614 +
      615 +        m = dupmsg(m);
      616 +        if (m == NULL)
      617 +                return (ENOSR);
      618 +
      619 +        return (mb_put_mbuf(mbp, m));
      620 +}
      621 +
      622 +/*
 579  623   * copies a uio scatter/gather list to an mbuf chain.
 580  624   */
 581  625  int
 582  626  mb_put_uio(struct mbchain *mbp, uio_t *uiop, size_t size)
 583  627  {
 584  628          size_t left;
 585  629          int mtype, error;
 586  630  
 587  631          mtype = (uio_isuserspace(uiop) ? MB_MUSER : MB_MSYSTEM);
 588  632          while (size > 0 && uiop->uio_resid) {
↓ open down ↓ 279 lines elided ↑ open up ↑
 868  912                                  *target++ = *s++;
 869  913                          continue;
 870  914                  }
 871  915                  target += count;
 872  916          }
 873  917          return (0);
 874  918  }
 875  919  
 876  920  /*
 877  921   * Get the next SIZE bytes as a separate mblk.
      922 + * Advances position in mdp by SIZE.
 878  923   */
 879  924  int
 880  925  md_get_mbuf(struct mdchain *mdp, int size, mblk_t **ret)
 881  926  {
 882  927          mblk_t *m, *rm;
 883  928  
 884  929          unsigned char *s;
 885  930          uint64_t diff;
 886  931          int off;
 887  932  
↓ open down ↓ 3 lines elided ↑ open up ↑
 891  936          m = mdp->md_cur;
 892  937          s = mdp->md_pos;
 893  938          ASSERT((m->b_rptr <= s) && (s <= m->b_wptr));
 894  939          diff = (uintptr_t)s - (uintptr_t)m->b_rptr;
 895  940          ASSERT(diff == (uint64_t)((int)diff));
 896  941          off = (int)diff;
 897  942  
 898  943          rm = m_copym(m, off, size, M_WAITOK);
 899  944          if (rm == NULL)
 900  945                  return (EBADRPC);
      946 +        (void) md_get_mem(mdp, NULL, size, MB_MSYSTEM);
 901  947  
 902  948          *ret = rm;
 903  949          return (0);
 904  950  }
 905  951  
 906  952  int
 907  953  md_get_uio(struct mdchain *mdp, uio_t *uiop, size_t size)
 908  954  {
 909  955          size_t left;
 910  956          int mtype, error;
↓ open down ↓ 157 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX