Bug #14999
closedSMB server mis-handles very long file names
100%
Description
From racktop:
BSR-7304 SMB server mis-handles very long file names
In production at least a few months.
Files
Updated by Joshua M. Clulow about 1 year ago
- External Bug set to racktop:BSR-7304
Updated by Gordon Ross about 1 year ago
- File longname1.snoop longname1.snoop added
I reproduced this and got a capture: longname1.snoop
The interesting thing in the capture is that we allow the create, but
the file we created has a truncated name. That's not ideal.
So what's going on? The create is in frame 44:
No. Time Source Destination Protocol Length Info 44 0.051257 192.168.202.1 192.168.202.132 SMB2 398 Create Request File: �������������������������������������������������������������������������������☮✝✝����☮☮.JPG Frame 44: 398 bytes on wire (3184 bits), 398 bytes captured (3184 bits) Ethernet II, Src: 16:7d:da:14:e7:64 (16:7d:da:14:e7:64), Dst: VMware_5a:4b:25 (00:0c:29:5a:4b:25) Internet Protocol Version 4, Src: 192.168.202.1, Dst: 192.168.202.132 Transmission Control Protocol, Src Port: 61269, Dst Port: 445, Seq: 2781, Ack: 2304, Len: 332 NetBIOS Session Service SMB2 (Server Message Block Protocol version 2) SMB2 Header Create Request (0x05) StructureSize: 0x0039 Oplock: No oplock (0x00) Impersonation level: Impersonation (2) Create Flags: 0x0000000000000000 Reserved: 0000000000000000 Access Mask: 0x00020087 File Attributes: 0x000000a0 Share Access: 0x00000007, Read, Write, Delete Disposition: Create (if file exists fail, else create it) (2) Create Options: 0x00000000 Filename [truncated]: ������������������������������������������������������������������������ Blob Offset: 0x00000130 Blob Length: 24 ExtraInfo SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST 0000 00 0c 29 5a 4b 25 16 7d da 14 e7 64 08 00 45 02 ..)ZK%.}...d..E. 0010 01 80 00 00 00 00 40 06 63 9f c0 a8 ca 01 c0 a8 ......@.c....... 0020 ca 84 ef 55 01 bd f4 b7 85 c6 e3 2d aa 9f 80 18 ...U.......-.... 0030 e2 00 75 c5 00 00 01 01 08 0a a8 8d a3 73 00 17 ..u..........s.. 0040 aa 0e 00 00 01 48 fe 53 4d 42 40 00 01 00 00 00 .....H.SMB@..... 0050 00 00 05 00 01 00 08 00 00 00 00 00 00 00 ed 01 ................ 0060 00 00 00 00 00 00 ff fe 00 00 02 00 00 00 5f 13 .............._. 0070 17 9e f9 01 00 00 be 34 d9 cd 19 ce e6 ae 0f 26 .......4.......& 0080 5a 15 24 3b 42 1c 39 00 00 00 02 00 00 00 00 00 Z.$;B.9......... 0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 00 ................ 00a0 02 00 a0 00 00 00 07 00 00 00 02 00 00 00 00 00 ................ 00b0 00 00 78 00 b8 00 30 01 00 00 18 00 00 00 # File name starts here . . . . . . . . . . . . v fd ff ..x...0......... 00c0 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 00d0 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 00e0 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 00f0 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 0100 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 0110 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 0120 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 0130 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 0140 fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff ................ 0150 fd ff fd ff fd ff fd ff fd ff fd ff 2e 26 1d 27 .............&.' 0160 1d 27 fd ff fd ff fd ff fd ff 2e 26 2e 26 2e 00 .'.........&.&.. 0170 4a 00 50 00 47 00 00 00 J.P.G...
That name is composed of about 160 xFFFD characters,
plus a mix of a few other, ending with ".JPG"
The challenge here for the SMB server is that all of
those xFFFD characters, when converted from UTF-16
into UTF-8 (what ZFS uses) turn into 3 bytes each.
UTF-8 (hex) 0xEF 0xBF 0xBD (efbfbd)
UTF-16 (hex) 0xFFFD (fffd)
That file name converted to UTF-8 looks like:
% hexdump longname1-utf8.txt 0000000 ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef 0000010 bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf 0000020 bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd 0000030 ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef 0000040 bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf 0000050 bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd 0000060 ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef 0000070 bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf 0000080 bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd 0000090 ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef 00000a0 bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf 00000b0 bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd 00000c0 ef bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef 00000d0 bf bd ef bf bd ef bf bd ef bf bd ef bf bd ef bf 00000e0 bd ef bf bd ef bf bd ef bf bd ef bf bd e2 98 ae 00000f0 e2 9c 9d e2 9c 9d ef bf bd ef bf bd ef bf bd ef 0000100 bf bd e2 98 ae e2 98 ae 2e 4a 50 47 00
As one can see, that's over the 256 char. limit imposed on
each component of a file name.
So we know we'll never be able to store this name, but
perhaps we should do better on returning an error when
the server figures out that the name is too long.
Updated by Gordon Ross about 1 year ago
It turns out that below the VFS layer (eg. ZFS) file name components longer than
MAXNAMELEN (256) are simply truncated. Normal user-space callers get the
error ENAMETOOLONG thanks to checks in pn_getcomponent, typically called via
3 28068 pn_getcomponent:return 0x4e 3 28493 lookuppnvp:return 0x4e 3 28535 lookuppnatcred:return 0x4e 3 28491 lookuppnat:return 0x4e 3 32116 vn_createat:return 0x4e 3 30515 vn_openat:return 0x4e
Code that calls the VFS directly needs to do it own truncation check.
I've added those checks in smb_pathname_reduce(), where we fill in
caller's last_component buffer (where truncation was happening).
Updated by Gordon Ross about 1 year ago
I also have a new smbtorture test for this kind of long name, which I'll push to our samba fork:
rt-samba ssh://git@github.com/racktopsystems/samba.git commit bf24aeef43ecf9a238c5e9337a32606363bf3560 (HEAD -> rt-eng-tort2, rt-samba/rt-eng-tort2) Author: Gordon Ross <gordon.w.ross@gmail.com> Date: Wed Sep 29 16:12:05 2021 -0400 Add smbtorture smb2.create.longname
Updated by Gordon Ross about 1 year ago
Testing:
new unit test: smbtorture ... smb2.create.longname
Copy the file in longname.zip onto a share and check that the name is the same.
This has been in production for several months.
Updated by Electric Monk 12 months ago
- Status changed from In Progress to Closed
- % Done changed from 90 to 100
git commit 46a7047cf9615f69c4e19c75c66b808b68695bbe
commit 46a7047cf9615f69c4e19c75c66b808b68695bbe Author: Gordon Ross <gwr@racktopsystems.com> Date: 2022-09-26T15:03:54.000Z 14999 SMB server mis-handles very long file names Reviewed-by: Garrett D'Amore <gdamore@damore.org> Reviewed by: Andy Stormont <astormont@racktopsystems.com> Reviewed-by: Jerry Jelinek <gjelinek@racktopsystems.com> Reviewed-by: Vitaliy Gusev <gusev.vitaliy@gmail.com> Reviewed by: Matt Barden <mbarden@tintri.com> Approved by: Dan McDonald <danmcd@mnx.io>