Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jul 2013 15:36:38 GMT
From:      Ralf Wenk <iz-rpi03@hs-karlsruhe.de>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/180438: [patch] mount_smbfs fails on arm because of wrong endianess assumption in libsmb
Message-ID:  <201307101536.r6AFacR3082463@oldred.freebsd.org>
Resent-Message-ID: <201307101540.r6AFe0uD049821@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         180438
>Category:       kern
>Synopsis:       [patch] mount_smbfs fails on arm because of wrong endianess assumption in libsmb
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 10 15:40:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Ralf Wenk
>Release:        FreeBSD 10.0-CURRENT arm
>Organization:
Hochschule Karlsruhe, University of Applied Sciences
>Environment:
FreeBSD raspberry-pi 10.0-CURRENT FreeBSD 10.0-CURRENT #1 r252777: Fri Jul  5 22:41:59 CEST 2013     root@IZ-FreeBSD1:/usr/obj/arm.armv6/rpi/head/sys/RPI-Bsc  arm
>Description:
When trying to mount an smb-share on arm with mount_smbfs I got the error message
"a bug somewhere in the nb_name* code".

Analysing the cause showed that nb_name_encode() in contrib/smbfs/lib/smb/nb_name.c
make assumptions about the layout of data (endianess) by writing at a u_char *
with casts to ushort * which are not true at (my) arm.

As a result the length information in the first byte of the encoded name gets
overwritten with a encoded nibble of the first character of the name.
This let nb_encname_len() calculate a different value as nb_name_len() and
nb_sockaddr() print out the error message above.
>How-To-Repeat:
Crosscompile libiconv libmchain smbfs modules for a arm CPU (RaspberryPi here).
Do not forget to compile mount_smbfs als well. The attached patch contains the
needed statements for arm as well. Then call
mount_smbfs -I mybox. //USER@MYBOX/home /mnt
>Fix:
The attached patch fixes nb_name_encode().

With the patch applied I have successfully mounted a smb share using the arm
system. I also verified the patch using a i386 system to be shure not to
introduce a bug into the other architectures.

Patch attached with submission follows:

Index: contrib/smbfs/lib/smb/nb_name.c
===================================================================
--- contrib/smbfs/lib/smb/nb_name.c	(revision 252777)
+++ contrib/smbfs/lib/smb/nb_name.c	(working copy)
@@ -143,18 +143,9 @@
 	return len;
 }
 
-#define	NBENCODE(c)	(htole16((u_short)(((u_char)(c) >> 4) | \
-			 (((u_char)(c) & 0xf) << 8)) + 0x4141))
+#define NBENCODEHIGH(c)	(0x41 + (u_char)(((c) & 0xF0) >> 4))
+#define NBENCODELOW(c)	(0x41 + (u_char)((c) & 0x0F))
 
-static void
-memsetw(char *dst, int n, u_short word)
-{
-	while (n--) {
-		*(u_short*)dst = word;
-		dst += 2;
-	}
-}
-
 int
 nb_name_encode(struct nb_name *np, u_char *dst)
 {
@@ -165,19 +156,25 @@
 	*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;
+		*cp++ = NBENCODEHIGH('*');
+		*cp++ = NBENCODELOW('*');
+		i = NB_NAMELEN - 1;
+		while (i-- > 0) {
+			*cp++ = NBENCODEHIGH(' ');
+			*cp++ = NBENCODELOW(' ');
+		}
 	} else {
-		for (i = 0; *name && i < NB_NAMELEN - 1; i++, cp += 2, name++)
-			*(u_short*)cp = NBENCODE(toupper(*name));
+		for (i = 0; *name && i < NB_NAMELEN - 1; i++, name++) {
+			*cp++ = NBENCODEHIGH(toupper(*name));
+			*cp++ = NBENCODELOW(toupper(*name));
+		}
 		i = NB_NAMELEN - i - 1;
-		if (i > 0) {
-			memsetw(cp, i, NBENCODE(' '));
-			cp += i * 2;
+		while (i-- > 0) {
+			*cp++ = NBENCODEHIGH(' ');
+			*cp++ = NBENCODELOW(' ');
 		}
-		*(u_short*)cp = NBENCODE(np->nn_type);
-		cp += 2;
+		*cp++ = NBENCODEHIGH(np->nn_type);
+		*cp++ = NBENCODELOW(np->nn_type);
 	}
 	*cp = 0;
 	if (np->nn_scope == NULL)
Index: lib/Makefile
===================================================================
--- lib/Makefile	(revision 252777)
+++ lib/Makefile	(working copy)
@@ -236,6 +236,10 @@
 _libsmb=	libsmb
 .endif
 
+.if ${MACHINE_CPUARCH} == "arm"
+_libsmb=	libsmb
+.endif
+
 .if ${MK_OPENSSL} != "no"
 _libmp=		libmp
 .endif
Index: usr.bin/Makefile.arm
===================================================================
--- usr.bin/Makefile.arm	(revision 252777)
+++ usr.bin/Makefile.arm	(working copy)
@@ -1,2 +1,3 @@
 # $FreeBSD$
 
+SUBDIR+=	smbutil
Index: usr.sbin/Makefile.arm
===================================================================
--- usr.sbin/Makefile.arm	(revision 252777)
+++ usr.sbin/Makefile.arm	(working copy)
@@ -2,3 +2,4 @@
 
 SUBDIR+=	ofwdump
 SUBDIR+=	kgmon
+SUBDIR+=	mount_smbfs


>Release-Note:
>Audit-Trail:
>Unformatted:



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