Project

General

Profile

Actions

Bug #14999

closed

SMB server mis-handles very long file names

Added by Toomas Soome 6 days ago. Updated about 20 hours ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
smb - SMB server and client
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:
External Bug:
racktop:BSR-7304

Description

From racktop:
BSR-7304 SMB server mis-handles very long file names
In production at least a few months.


Files

longname1.snoop (2.72 MB) longname1.snoop Gordon Ross, 2022-09-21 10:57 PM
longname.zip (2.35 MB) longname.zip Gordon Ross, 2022-09-21 11:04 PM
Actions #1

Updated by Electric Monk 6 days ago

  • Gerrit CR set to 2378
Actions #2

Updated by Joshua M. Clulow 6 days ago

  • External Bug set to racktop:BSR-7304
Actions #3

Updated by Gordon Ross 6 days ago

  • Description updated (diff)
Actions #4

Updated by Gordon Ross 6 days ago

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.

Actions #5

Updated by Gordon Ross 6 days 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).

Actions #6

Updated by Gordon Ross 6 days 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

Actions #7

Updated by Gordon Ross 6 days 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.

Actions #8

Updated by Gordon Ross 6 days ago

Actions #9

Updated by Electric Monk about 20 hours 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>

Actions

Also available in: Atom PDF