Bug 1383968

Summary: Creating a symlink with a colon in its name results in a corrupted file name
Product: [Fedora] Fedora Reporter: Jan Synacek <jsynacek>
Component: kernelAssignee: Kernel Maintainer List <kernel-maint>
Status: CLOSED INSUFFICIENT_DATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 24CC: abokovoy, anoopcs, asn, eggert, gansalmon, gdeschner, ichavero, itamar, jonathan, jrivera, kernel-maint, lists, lmohanty, madam, madhu.chinakonda, mchehab, sbose, ssorce
Target Milestone: ---Flags: jforbes: needinfo?
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-04-28 17:17:26 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Jan Synacek 2016-10-12 09:25:21 UTC
Description of problem:
Compiling and running the following will result in a corrupted filename.

#include <unistd.h>
int main (void) { return symlink ("a:b", "f") != 0; }

The symlink has to be created on a CIFS mount. The colon then gets substituted for U+F022.


Version-Release number of selected component (if applicable):
samba-4.4.6-1.fc24.x86_64


Steps to Reproduce:
1. See description.


Actual results:
Corrupted filename.


Expected results:
Filename with a colon in it.


Additional info:
Running "ln -s <target> a:b" works.

Comment 1 Alexander Bokovoy 2016-10-12 10:08:25 UTC
This is not a bug in Samba.

MS-CIFS specification forbids a number of characters to be present in the file names, see MS-CIFS 2.2.1.1.1. cifs.ko kernel module obeys the restriction and does not allow to use them in file names. In case 'mapchars' option was specified when mounting the share, cifs.ko module maps the characters except a backslash to the range above 0xF000, so colon becomes 0xF022. This only works with SMB servers supporting Unicode on the wire (Samba does support it), but Samba does not allow specifying the original, non-translated characters in any case, to be compatible with the MS-CIFS specification. Windows POSIX emulation does the translation as well.

By default cifs.ko does not do the translation, so if you see the translated character it means 'mapchars' option was specified in the mount options on one client and then without 'mapchars' on another. Once you started mapping characters, you need to always specify 'mapchars' when mounting the share or otherwise you'll get 'corrupted' characters back. They are stored converted on the SMB server side.

For example, on F24:

[root@f24-master ~]# mount -t cifs //`hostname`/testshare /mnt/ -o mapchars,user=admin
Password for admin@//f24-master.ipa.ad.test/testshare:  ********
[root@f24-master ~]# mount|grep testshare

//f24-master.ipa.ad.test/testshare on /mnt type cifs (rw,relatime,vers=1.0,cache=strict,username=admin,domain=IPAAD,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.5.117,unix,posixpaths,serverino,mapchars,acl,rsize=1048576,wsize=65536,echo_interval=60,actimeo=1,user=admin)
[root@f24-master ~]# touch /mnt/a:b
[root@f24-master ~]# ls -la /mnt/a:b
-rw-r--r--+ 1 admin admins 0 Oct 12 13:01 /mnt/a:b
[root@f24-master ~]# ls -la /mnt/
total 0
drwxrwxr-x+  2 root  root     0 Oct 12 13:01 .
dr-xr-xr-x. 17 root  root   259 May 31 11:09 ..
-rw-r--r--+  1 admin admins   0 Oct 12 13:01 a:b
[root@f24-master ~]# ls -la /srv/myshare/
total 0
drwxrwxr-x+ 2 root  root   19 Oct 12 13:01 .
drwxr-xr-x. 3 root  root   21 Oct 12 12:58 ..
-rw-r--r--. 1 admin admins  0 Oct 12 13:01 ab
[root@f24-master ~]# umount /mnt
[root@f24-master ~]# mount -t cifs //`hostname`/testshare /mnt/ -o user=admin
Password for admin@//f24-master.ipa.ad.test/testshare:  ********
[root@f24-master ~]# ls -la /mnt/
total 0
drwxrwxr-x+  2 root  root     0 Oct 12 13:01 .
dr-xr-xr-x. 17 root  root   259 May 31 11:09 ..
-rw-r--r--+  1 admin admins   0 Oct 12 13:01 ab
[root@f24-master ~]# 

So you can see that doing mount without mapchars option does not change filenames which were created when using mapchars option.

Comment 2 Paul Eggert 2016-10-12 15:39:20 UTC
I observed the problem on Fedora 24 without using any mapchars option, and without using multiple clients or unmounting and remounting the CIFS file system. I created a simple share using the recipe at the start of <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24656#c5>, appending this to the otherwise-stock /etc/samba/smb.conf:

[public]
        browseable = Yes
        guest ok = Yes
        path = /tmp/samba
        read only = No

Although I normally don't run Samba, I enabled it as follows:

setsebool -P samba_export_all_rw 1
service smb restart
mount -t cifs //penguin.cs.ucla.edu/public /mnt/tmp -o guest
cd /mnt/tmp

I then compiled and ran the following program:

#include <unistd.h>
int main (void) { return symlink ("a:b", "f") != 0; }

This created a symbolic link from "f" to "a<F022>b", where "<F022>" stands for the UTF-8 representation for U+F022, i.e., the bytes EF, 80, A2.

Comment 3 Alexander Bokovoy 2016-10-12 16:28:27 UTC
I can see that cifs.ko actually passing U+F022 on the wire because this is what Samba receives from the network:

[2016/10/12 19:16:02.473717, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../lib/util/util.c:559(dump_data)
  [0000] 00 00 00 09 02 00 00 00   00 2F 00 61 00 22 F0 62   ........ ./.a.".b
  [0010] 00 00 00 02 00 00 00 12   00 00 00 A4 81 00 00 00   ........ ........
  [0020] 00 00 00 00 02                                     ..... 
[2016/10/12 19:16:02.473743,  3, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/process.c:1538(switch_message)
  switch message SMBtrans2 (pid 3889) conn 0x555d829c0680
[2016/10/12 19:16:02.473750,  4, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/uid.c:384(change_to_user)
  Skipping user change - already user
[2016/10/12 19:16:02.473772,  5, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/filename.c:276(unix_convert)
  unix_convert called on file "ab"
[2016/10/12 19:16:02.473777,  5, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/filename.c:469(unix_convert)
  unix_convert begin: name = ab, dirpath = , start = ab
[2016/10/12 19:16:02.473788, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0), class=vfs] ../source3/smbd/vfs.c:1160(check_reduced_name)
  check_reduced_name: check_reduced_name [ab] [/srv/myshare]
[2016/10/12 19:16:02.473798, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0), class=vfs] ../source3/smbd/vfs.c:1220(check_reduced_name)
  check_reduced_name realpath [ab] -> [/srv/myshare/ab]
[2016/10/12 19:16:02.473803,  5, pid=3889, effective(903200000, 903200000), real(903200000, 0), class=vfs] ../source3/smbd/vfs.c:1307(check_reduced_name)
  check_reduced_name: ab reduced to /srv/myshare/ab
[2016/10/12 19:16:02.473807,  3, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/trans2.c:8739(call_trans2setfilepathinfo)
  call_trans2setfilepathinfo(6) ab (fnum [fsp is NULL]) info_level=521 totdata=18
[2016/10/12 19:16:02.473813,  3, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/trans2.c:8299(smbd_do_setfilepathinfo)
  smbd_do_setfilepathinfo: ab (fnum [fsp is NULL]) info_level=521 totdata=18
[2016/10/12 19:16:02.473818, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/trans2.c:8058(smb_posix_open)
  smb_posix_open: file ab, smb_posix_flags = 0, mode 0644
[2016/10/12 19:16:02.473822, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/open.c:5030(create_file_default)
  create_file: access_mask = 0x112 file_attributes = 0x10001a4, share_access = 0x7, create_disposition = 0x3 create_options = 0x40 oplock_request = 0x1 private_flags = 0x0 root_dir_fid = 0x0, ea_list = 0x(nil), sd = 0x(nil), fname = ab
[2016/10/12 19:16:02.473828, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/open.c:4505(create_file_unixpath)
  create_file_unixpath: access_mask = 0x112 file_attributes = 0x10001a4, share_access = 0x7, create_disposition = 0x3 create_options = 0x40 oplock_request = 0x1 private_flags = 0x0 ea_list = 0x(nil), sd = 0x(nil), fname = ab

So, the issue is in cifs.ko, it seems, where it tries to translate the name despite using UNIX extensions.

Comment 4 Justin M. Forbes 2017-04-11 14:56:08 UTC
*********** MASS BUG UPDATE **************

We apologize for the inconvenience.  There are a large number of bugs to go through and several of them have gone stale.  Due to this, we are doing a mass bug update across all of the Fedora 24 kernel bugs.

Fedora 25 has now been rebased to 4.10.9-100.fc24.  Please test this kernel update (or newer) and let us know if you issue has been resolved or if it is still present with the newer kernel.

If you have moved on to Fedora 26, and are still experiencing this issue, please change the version to Fedora 26.

If you experience different issues, please open a new bug report for those.

Comment 5 Justin M. Forbes 2017-04-28 17:17:26 UTC
*********** MASS BUG UPDATE **************
This bug is being closed with INSUFFICIENT_DATA as there has not been a response in 2 weeks. If you are still experiencing this issue, please reopen and attach the 
relevant data from the latest kernel you are running and any data that might have been requested previously.