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)

@@ -31,13 +31,14 @@
  *
  * $FreeBSD: src/sys/kern/subr_mchain.c,v 1.1 2001/02/24 15:44:29 bp Exp $
  */
 
 /*
- * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/errno.h>

@@ -111,10 +112,13 @@
  * 4K fits nicely in 3 Ethernet frames (3 * 1500)
  * leaving about 500 bytes for protocol headers.
  */
 #define MLEN    4096
 
+#if (MLEN < SMB2_HDRLEN)
+#error "MLEN can't fit a contiguous SMB2 header"
+#endif
 
 /*
  * Some UIO routines.
  * Taken from Darwin Sourcecs.
  */

@@ -418,11 +422,27 @@
         }
 
         return (0);
 }
 
+/*
+ * Adds padding to 8 byte boundary
+ */
 int
+mb_put_align8(struct mbchain *mbp)
+{
+        static const char zeros[8] = { 0 };
+        int pad_len = 0;
+
+        if ((mbp->mb_count % 8) != 0) {
+                pad_len = 8 - (mbp->mb_count % 8);
+                MB_PUT_INLINE(mbp, zeros, pad_len);
+        }
+        return (0);
+}
+
+int
 mb_put_uint8(struct mbchain *mbp, u_int8_t x)
 {
         u_int8_t v = x;
         MB_PUT_INLINE(mbp, &v, sizeof (v));
 }

@@ -535,10 +555,11 @@
         return (0);
 }
 
 /*
  * Append an mblk to the chain.
+ * Note: The mblk_t *m is consumed.
  */
 int
 mb_put_mbuf(struct mbchain *mbp, mblk_t *m)
 {
         mblk_t *nm, *tail_mb;

@@ -574,10 +595,33 @@
 
         return (0);
 }
 
 /*
+ * Put an mbchain into another mbchain
+ * Leave sub_mbp untouched.
+ */
+int
+mb_put_mbchain(struct mbchain *mbp, struct mbchain *sub_mbp)
+{
+        mblk_t *m;
+
+        if (sub_mbp == NULL)
+                return (0);
+
+        m = sub_mbp->mb_top;
+        if (m == NULL)
+                return (0);
+
+        m = dupmsg(m);
+        if (m == NULL)
+                return (ENOSR);
+
+        return (mb_put_mbuf(mbp, m));
+}
+
+/*
  * copies a uio scatter/gather list to an mbuf chain.
  */
 int
 mb_put_uio(struct mbchain *mbp, uio_t *uiop, size_t size)
 {

@@ -873,10 +917,11 @@
         return (0);
 }
 
 /*
  * Get the next SIZE bytes as a separate mblk.
+ * Advances position in mdp by SIZE.
  */
 int
 md_get_mbuf(struct mdchain *mdp, int size, mblk_t **ret)
 {
         mblk_t *m, *rm;

@@ -896,10 +941,11 @@
         off = (int)diff;
 
         rm = m_copym(m, off, size, M_WAITOK);
         if (rm == NULL)
                 return (EBADRPC);
+        (void) md_get_mem(mdp, NULL, size, MB_MSYSTEM);
 
         *ret = rm;
         return (0);
 }