[BUG] cifs: readlink/stat of macOS-served symlinks returns -EINVAL on 6.18 (works on 5.10)
Carl Johnson <[email protected]>
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
Hello,
Reading a server-side symlink from Apple's built-in SMB server (macOS) fails
with -EINVAL on a 6.18 client, while the identical share on the identical
server works on a 5.10 client. This looks like a regression in how the client
handles STATUS_STOPPED_ON_SYMLINK when the server returns no inline symlink
error data.
Environment
-----------
Broken client : Debian 13, kernel 6.18.38 (armv7l/BeagleBone), cifs-utils 7.4
Working client: Debian 12, kernel 5.10.168 (armv7l) -- same server + share
Server : macOS 26.5.2 (build 25F84), built-in SMB server
Share content : ordinary symlinks, e.g. Config.json -> Templates/Globe/Config.json
Symptom (6.18)
--------------
$ ls -la .../Config
l????????? ? ? ? ? ? Config.json
$ readlink .../Config/Config.json # prints nothing, exit 1
$ stat .../Config/Config.json
stat: cannot statx '...': Invalid argument
dmesg: CIFS: Status code returned 0x8000002d STATUS_STOPPED_ON_SYMLINKThe same operations on 5.10 return the correct target. Accessing the symlink's
target path directly on the 6.18 mount works fine, so the reparse data is
retrievable; only resolving the link itself fails.Not a mount-option issue: tried symlink={mfsymlinks,nfs,native,<default>} x
reparse={nfs,<none>}, vers=3.0 and vers=default -- all fail identically.
Root cause (from a traceSMB capture)
------------------------------------
On opening a path whose final component is a symlink, macOS returns an SMB2
CREATE response with STATUS_STOPPED_ON_SYMLINK (0x8000002d) and an SMB2 Error
Response whose ByteCount is 0 -- i.e. it does NOT inline a Symbolic Link Error
Response (MS-SMB2 2.2.2.2.1) carrying the target: SMB2 hdr : Status=0x8000002d Command=0x0005 (CREATE) Flags=SERVER_TO_REDIR|SIGNED
Error Rsp: StructureSize=0x0009 ErrorContextCount=0 ByteCount=0x00000000 (no ErrorData)Raw CREATE response (traceSMB, cleartext, sealing disabled; 16 bytes/line): 53fe 424d 0040 0001 002d 8000 0005 000a [email protected].......
0009 0000 0050 0000 001f 0000 0000 0000 Flags=9 NextCmd=0x50 MsgId=0x1f
0df9 0000 0002 0000 0018 0000 4b93 d0c6
8361 3db2 1ea1 3269 5d81 d833 14c5 6a0f (signature)
0009 0000 0000 0000 ... StructSize=9, ByteCount=05.10 tolerates the empty error data and obtains the target via a follow-up
open with FILE_OPEN_REPARSE_POINT + FSCTL_GET_REPARSE_POINT. 6.18 appears to
assume the target is always inline in the symlink error response and returns
-EINVAL when it is absent, rather than falling back to FSCTL_GET_REPARSE_POINT.
Suggested direction
-------------------
When STATUS_STOPPED_ON_SYMLINK is returned with an empty/insufficient Symbolic
Link Error Response, fall back to reading the reparse point
(FILE_OPEN_REPARSE_POINT + FSCTL_GET_REPARSE_POINT) instead of returning
-EINVAL, restoring the 5.10 behaviour for Apple SMB servers.I can capture full traces at higher verbosity and test patches on the 6.18
box on request.
Thanks,
--Carl