Bug 6767 - cifs.mount: mapchars + utf8 = loop
Summary: cifs.mount: mapchars + utf8 = loop
Status: RESOLVED FIXED
Alias: None
Product: Samba 3.4
Classification: Unclassified
Component: Client Tools (show other bugs)
Version: unspecified
Hardware: Other Linux
: P3 normal
Target Milestone: ---
Assignee: Jeff Layton
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-09-28 09:41 UTC by Chuck Short (mail address dead)
Modified: 2017-11-07 14:21 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chuck Short (mail address dead) 2009-09-28 09:41:27 UTC
Hello,

This was orginally reported in http://bugs.launchpad.net/bugs/260396.

If you have any questions please let me know.

Regards
chuck
Comment 1 Jeff Layton 2009-10-06 06:46:27 UTC
What's the latest kernel on which you've tested and seen this behavior?
Comment 2 Jeff Layton 2009-10-06 06:47:42 UTC
If the problem is seen in very recent kernels (2.6.30 or 2.6.31), then please outline some steps to reproduce the problem.
Comment 3 Karolin Seeger 2010-05-26 08:09:01 UTC
Updating component.
Comment 4 Jeff Layton 2010-05-26 08:28:22 UTC
No response in several months. Closing bug.
Comment 5 Stanislas Hodur 2010-05-27 08:20:21 UTC
The bug is doing well, as of Ubuntu 10.4, kernel 2.6.32-22-generic :-(
so it would be nice if someone could REOPEN it.

A few steps to reproduce the problem -- see bugs.launchpad.net

WITHOUT mapchars (ok):
# mount -t cifs //aserver/whatever whatever -o iocharset=utf8
# ls whatever
sprzęt
# ls whatever/sprzęt
file1 file2

WITH mapchars (wrong):
# mount -t cifs //aserver/whatever whatever -o iocharset=utf8,mapchars
# ls whatever
sprzęt
# ls whatever/sprzęt
sprzęt
# ls -l whatever/sprzęt/sprzęt
ls: cannot access whatever/sprzęt/sprzęt: No such file or directory

It happens if you have both mapchars and utf8, and the directory name contains a non-ascii character, say [áàéęź]. 
Comment 6 Jeff Layton 2010-05-27 08:34:05 UTC
Reopening bug since there is now a reproducer provided.
Comment 7 muelleki 2011-04-12 20:26:14 UTC
This bug affects me, too.

Reproduced with a Mac OS X server, a Debian client, and pam_mount.
Comment 8 Adam Williamson 2011-10-07 20:06:18 UTC
Reproduced on Fedora 16 (kernel 3.1rc8) with a DNS-323 in the role of server (2.6.12.6-arm1). mapchars allows me to create filenames with ? in them (which is a big deal for songs) but screws up directories with Japanese characters in their names as described here (ditto a big deal for songs...)
Comment 9 Baldvin Kovacs 2011-10-09 15:23:03 UTC
Very interesting. The same directory (called Öőú, for testing) works with either

iocharset=latin2,mapchars

or

iocharset=utf8

but not with

iocharset=utf8,mapchars
Comment 10 Baldvin Kovacs 2011-10-09 15:24:26 UTC
(In reply to comment #9)
> Very interesting. The same directory (called Öőú, for testing) works with
> either
> 
> iocharset=latin2,mapchars
sorry, iso8859-2, not latin2

> 
> or
> 
> iocharset=utf8
> 
> but not with
> 
> iocharset=utf8,mapchars
Comment 11 Baldvin Kovacs 2011-10-09 15:50:36 UTC
In fs/cifs/readdir.c, there's this fragment:

        if (unicode) {
                pqst->len = cifs_from_ucs2((char *) pqst->name,
                                           (__le16 *) filename,
                                           UNICODE_NAME_MAX,
                                           min(len, max_len), nlt,
                                           cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                pqst->len -= nls_nullsize(nlt);
        } else {
                pqst->name = filename;
                pqst->len = len;
        }

I ain't no kernel programmer, but this seems to be suspicious.

In one branch, we simply change the value of pqst->name, in the other, we copy over to it.... :)

Baldvin




(In reply to comment #9)
> Very interesting. The same directory (called Öőú, for testing) works with
> either
> 
> iocharset=latin2,mapchars
> 
> or
> 
> iocharset=utf8
> 
> but not with
> 
> iocharset=utf8,mapchars
Comment 12 Baldvin Kovacs 2011-10-09 16:03:08 UTC
(In reply to comment #11)
> In fs/cifs/readdir.c, there's this fragment:
> 
>         if (unicode) {
>                 pqst->len = cifs_from_ucs2((char *) pqst->name,
>                                            (__le16 *) filename,
>                                            UNICODE_NAME_MAX,
>                                            min(len, max_len), nlt,
>                                            cifs_sb->mnt_cifs_flags &
>                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
>                 pqst->len -= nls_nullsize(nlt);
>         } else {
>                 pqst->name = filename;
>                 pqst->len = len;
>         }
> 
> I ain't no kernel programmer, but this seems to be suspicious.

... suspicious, but correct. It is initialized to a scratch buffer. Sorry.
Comment 13 Baldvin Kovacs 2011-10-09 20:07:58 UTC
Oct  9 21:48:52 medve kernel: [  614.141444]  /home/baldvin/samba/linux-2.6.32/fs/cifs/readdir.c: CIFS VFS: in cifs_readdir as Xid: 53 with uid: 0
Oct  9 21:48:52 medve kernel: [  614.141447]  /home/baldvin/samba/linux-2.6.32/fs/cifs/readdir.c: Full path: \cdk2\Öőú start at: 2
Oct  9 21:48:52 medve kernel: [  614.141448]  /home/baldvin/samba/linux-2.6.32/fs/cifs/cifssmb.c: In FindFirst for \cdk2\Öőú
Oct  9 21:48:52 medve kernel: [  614.141451]  /home/baldvin/samba/linux-2.6.32/fs/cifs/transport.c: For smb_command 50
Oct  9 21:48:52 medve kernel: [  614.141452]  /home/baldvin/samba/linux-2.6.32/fs/cifs/transport.c: Sending smb:  total_len 112
Oct  9 21:48:52 medve kernel: [  614.141453] | 0x00 0x00 0x00 0x6c 0xff 0x53 0x4d 0x42  |  _ _ _ l <FF> S M B
Oct  9 21:48:52 medve kernel: [  614.141458] | 0x32 0x00 0x00 0x00 0x00 0x00 0x01 0xc0  |  2 _ _ _ _ _ _ <C0>
Oct  9 21:48:52 medve kernel: [  614.141461] | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00  |  _ _ _ _ _ _ _ _
Oct  9 21:48:52 medve kernel: [  614.141465] | 0x00 0x00 0x00 0x00 0x00 0x08 0x7c 0x08  |  _ _ _ _ _ _ | _
Oct  9 21:48:52 medve kernel: [  614.141469] | 0x00 0x08 0x20 0x00 0x0f 0x2a 0x00 0x00  |  _ _   _ _ * _ _
Oct  9 21:48:52 medve kernel: [  614.141473] | 0x00 0x0a 0x00 0x00 0x10 0x00 0x00 0x00  |  _ _ _ _ _ _ _ _
Oct  9 21:48:52 medve kernel: [  614.141477] | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x2a  |  _ _ _ _ _ _ _ *
Oct  9 21:48:52 medve kernel: [  614.141481] | 0x00 0x42 0x00 0x00 0x00 0x00 0x00 0x01  |  _ B _ _ _ _ _ _
Oct  9 21:48:52 medve kernel: [  614.141485] | 0x00 0x01 0x00 0x2b 0x00 0x00 0x17 0x00  |  _ _ _ + _ _ _ _
Oct  9 21:48:52 medve kernel: [  614.141488] | 0x96 0x00 0x06 0x00 0x05 0x01 0x00 0x00  |  _ _ _ _ _ _ _ _
Oct  9 21:48:52 medve kernel: [  614.141492] | 0x00 0x00 0x5c 0x00 0x63 0x00 0x64 0x00  |  _ _ \ _ c _ d _
Oct  9 21:48:52 medve kernel: [  614.141496] | 0x6b 0x00 0x32 0x00 0x5c 0x00 0xd6 0x00  |  k _ 2 _ \ _ <D6> _
Oct  9 21:48:52 medve kernel: [  614.141500] | 0x51 0x01 0xfa 0x00 0x00 0x00 0x00 0x00  |  Q _ <FA> _ _ _ _ _
Oct  9 21:48:52 medve kernel: [  614.141504] | 0x00 0x00 0x5c 0x00 0x2a 0x00 0x00 0x00  |  _ _ \ _ * _ _ _
Oct  9 21:48:52 medve kernel: [  614.141508]  |  _ _ \ _ * _ _ _

Why the extra 00's after Öőú and \* ? This can be a smoking gun, because the extra 00's can mean that we want to FindFirst for \cdk2\Öőú\*, but rather the receiving system stops at trailing 0 after ú?
Comment 14 Baldvin Kovacs 2011-10-09 20:12:41 UTC
Heh, return i is the incorrect piece, in cifsConvertToUCS.
Comment 15 Baldvin Kovacs 2011-10-09 22:30:58 UTC
I've got a fix --- tested it, works beautifully. Quite simple:


--- orig/linux-2.6.32/fs/cifs/misc.c	2009-12-03 04:51:21.000000000 +0100
+++ linux-2.6.32/fs/cifs/misc.c	2011-10-09 22:25:10.767951322 +0200
@@ -713,7 +713,7 @@
 	}
 
 ctoUCS_out:
-	return i;
+	return j;
 }
 
 void


Best,
Baldvin
Comment 16 Jeff Layton 2011-10-10 12:34:46 UTC
Nice work. That patch looks correct to me too. The only additional thing I'd probably do is revise the comments above cifsConvertToUCS() to mention what that function is supposed to return (the number of wide characters in the resulting string, minus any NULL termination).

Would you care to post that patch to linux-cifs@vger.kernel.org? It should probably get cc'ed to stable as well.
Comment 17 Björn Jacke 2017-11-07 13:57:48 UTC
the code changed quite a bit in the meantime.

Jeff: is this bug fixed also these days?
Comment 18 Jeff Layton 2017-11-07 14:21:43 UTC
Yes, it was fixed upstream in c73f693989d7a7d99ec66a7065295a0c93d0b127.