]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: fix CreateOptions sanitization clobbering the whole field
authorDaeMyung Kang <charsyam@gmail.com>
Mon, 20 Apr 2026 17:51:25 +0000 (02:51 +0900)
committerSteve French <stfrench@microsoft.com>
Wed, 22 Apr 2026 13:11:23 +0000 (08:11 -0500)
smb2_open() attempts to clear conflicting CreateOptions bits
(FILE_SEQUENTIAL_ONLY_LE together with FILE_RANDOM_ACCESS_LE, and
FILE_NO_COMPRESSION_LE on a directory open), but uses a plain
assignment of the bitwise negation of the target flag:

req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);

This replaces the entire field with 0xFFFFFFFB / 0xFFFFFFEF rather
than clearing a single bit. With the SEQUENTIAL/RANDOM case, the
next check for FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION |
FILE_RESERVE_OPFILTER_LE then trivially matches and a legitimate
request is rejected with -EOPNOTSUPP. With the NO_COMPRESSION case,
every downstream test (FILE_DELETE_ON_CLOSE, etc.) operates on a
corrupted CreateOptions value.

Use &= ~FLAG to clear only the intended bit in both places.

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

index a7abef1b208adaacfcb76b9f836f132618966509..939089304052a865f93ad4d960821feeb18f4bf4 100644 (file)
@@ -3057,7 +3057,7 @@ int smb2_open(struct ksmbd_work *work)
        } else {
                if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE &&
                    req->CreateOptions & FILE_RANDOM_ACCESS_LE)
-                       req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
+                       req->CreateOptions &= ~FILE_SEQUENTIAL_ONLY_LE;
 
                if (req->CreateOptions &
                    (FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION |
@@ -3071,7 +3071,7 @@ int smb2_open(struct ksmbd_work *work)
                                rc = -EINVAL;
                                goto err_out2;
                        } else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) {
-                               req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);
+                               req->CreateOptions &= ~FILE_NO_COMPRESSION_LE;
                        }
                }
        }