]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ksmbd: validate :: stream type against directory create
authorNamjae Jeon <linkinjeon@kernel.org>
Sun, 21 Jun 2026 10:52:55 +0000 (19:52 +0900)
committerSteve French <stfrench@microsoft.com>
Tue, 23 Jun 2026 01:15:06 +0000 (20:15 -0500)
smb2.streams.dir opens <dir>::$DATA with FILE_DIRECTORY_FILE and expects
STATUS_NOT_A_DIRECTORY, then opens <dir>::$DATA without it and expects
STATUS_FILE_IS_A_DIRECTORY.

Commit "treat unnamed DATA stream as base file" canonicalizes the ::$DATA
suffix to a NULL stream name so the open continues through the base-file
path. That skipped the stream/directory type validation, which was
guarded by "if (stream_name)", so opening a directory's ::$DATA stream
with FILE_DIRECTORY_FILE incorrectly returned STATUS_OK and a plain open
of it no longer reported STATUS_FILE_IS_A_DIRECTORY.

parse_stream_name() still records the explicit $DATA type in s_type even
when it clears stream_name.  Run the data-stream vs directory validation
whenever s_type is DATA_STREAM, not only when stream_name is set, so the
canonicalized ::$DATA open is rejected with the correct status.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/smb2pdu.c

index 705cef655702b900c5bb498f9462342b4e73c103..c0d3062e4d936df7656ca8af167a8cab138c664d 100644 (file)
@@ -3453,7 +3453,14 @@ int smb2_open(struct ksmbd_work *work)
                rc = 0;
        }
 
-       if (stream_name) {
+       /*
+        * An explicit ::$DATA suffix names the unnamed data stream and is
+        * canonicalized to a NULL stream name (base file), but the request
+        * still has to be validated against the data-stream type, e.g. opening
+        * <dir>::$DATA with FILE_DIRECTORY_FILE must fail with
+        * STATUS_NOT_A_DIRECTORY.
+        */
+       if (stream_name || s_type == DATA_STREAM) {
                if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
                        if (s_type == DATA_STREAM) {
                                rc = -EIO;