Author: ian
Date: Mon Dec 21 17:17:00 2015
New Revision: 292552
URL: https://svnweb.freebsd.org/changeset/base/292552

Log:
  Avoid unaligned memory accesses when encoding netbios names in libsmb.
  
  The current code for encoding a netbios name converts each byte to a 16-bit
  value and stores the result by casting a char* to u_short*, resulting in
  alignment faults on strict-alignment platforms.
  
  This change reimplements the encoding routine using only byte accesses to
  memory. There is no particular reason to work with 16-bit values just
  because the encoding process creates two bytes of output for every byte of
  input. Working a byte at at time also avoids endian problems for big-endian
  platforms.
  
  PR:           180438
  PR:           189415
  Differential Revision:        https://reviews.freebsd.org/D4622

Modified:
  head/contrib/smbfs/lib/smb/nb_name.c

Modified: head/contrib/smbfs/lib/smb/nb_name.c
==============================================================================
--- head/contrib/smbfs/lib/smb/nb_name.c        Mon Dec 21 17:15:03 2015        
(r292551)
+++ head/contrib/smbfs/lib/smb/nb_name.c        Mon Dec 21 17:17:00 2015        
(r292552)
@@ -143,15 +143,13 @@ nb_encname_len(const char *str)
        return len;
 }
 
-#define        NBENCODE(c)     (htole16((u_short)(((u_char)(c) >> 4) | \
-                        (((u_char)(c) & 0xf) << 8)) + 0x4141))
-
-static void
-memsetw(char *dst, int n, u_short word)
+static inline void
+nb_char_encode(u_char **ptr, u_char c, int n)
 {
+
        while (n--) {
-               *(u_short*)dst = word;
-               dst += 2;
+               *(*ptr)++ = 0x41 + (c >> 4);
+               *(*ptr)++ = 0x41 + (c & 0x0f);
        }
 }
 
@@ -165,19 +163,15 @@ nb_name_encode(struct nb_name *np, u_cha
        *cp++ = NB_ENCNAMELEN;
        name = np->nn_name;
        if (name[0] == '*' && name[1] == 0) {
-               *(u_short*)cp = NBENCODE('*');
-               memsetw(cp + 2, NB_NAMELEN - 1, NBENCODE(' '));
-               cp += NB_ENCNAMELEN;
+               nb_char_encode(&cp, '*', 1);
+               nb_char_encode(&cp, ' ', NB_NAMELEN - 1);
        } else {
-               for (i = 0; *name && i < NB_NAMELEN - 1; i++, cp += 2, name++)
-                       *(u_short*)cp = NBENCODE(toupper(*name));
-               i = NB_NAMELEN - i - 1;
-               if (i > 0) {
-                       memsetw(cp, i, NBENCODE(' '));
-                       cp += i * 2;
-               }
-               *(u_short*)cp = NBENCODE(np->nn_type);
-               cp += 2;
+               for (i = 0; i < NB_NAMELEN - 1; i++)
+                       if (*name != 0)
+                               nb_char_encode(&cp, toupper(*name++), 1);
+                       else
+                               nb_char_encode(&cp, ' ', 1);
+               nb_char_encode(&cp, np->nn_type, 1);
        }
        *cp = 0;
        if (np->nn_scope == NULL)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to