Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Dec 2015 17:17:00 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r292552 - head/contrib/smbfs/lib/smb
Message-ID:  <201512211717.tBLHH0HK031172@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512211717.tBLHH0HK031172>