]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cifs: Fix access_flags_to_smbopen_mode
authorPali Rohár <pali@kernel.org>
Sun, 17 Nov 2024 10:50:18 +0000 (11:50 +0100)
committerSteve French <stfrench@microsoft.com>
Tue, 1 Apr 2025 06:54:17 +0000 (01:54 -0500)
When converting access_flags to SMBOPEN mode, check for all possible access
flags, not only GENERIC_READ and GENERIC_WRITE flags.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifssmb.c

index 29dcb88392e5cd334b734333dae06b258a864eea..60cb264a01e5110cc37c215f11bc94ae064075d4 100644 (file)
@@ -1041,15 +1041,31 @@ static __u16 convert_disposition(int disposition)
 static int
 access_flags_to_smbopen_mode(const int access_flags)
 {
-       int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
-
-       if (masked_flags == GENERIC_READ)
-               return SMBOPEN_READ;
-       else if (masked_flags == GENERIC_WRITE)
+       /*
+        * SYSTEM_SECURITY grants both read and write access to SACL, treat is as read/write.
+        * MAXIMUM_ALLOWED grants as many access as possible, so treat it as read/write too.
+        * SYNCHRONIZE as is does not grant any specific access, so do not check its mask.
+        * If only SYNCHRONIZE bit is specified then fallback to read access.
+        */
+       bool with_write_flags = access_flags & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA |
+                                               FILE_DELETE_CHILD | FILE_WRITE_ATTRIBUTES | DELETE |
+                                               WRITE_DAC | WRITE_OWNER | SYSTEM_SECURITY |
+                                               MAXIMUM_ALLOWED | GENERIC_WRITE | GENERIC_ALL);
+       bool with_read_flags = access_flags & (FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE |
+                                               FILE_READ_ATTRIBUTES | READ_CONTROL |
+                                               SYSTEM_SECURITY | MAXIMUM_ALLOWED | GENERIC_ALL |
+                                               GENERIC_EXECUTE | GENERIC_READ);
+       bool with_execute_flags = access_flags & (FILE_EXECUTE | MAXIMUM_ALLOWED | GENERIC_ALL |
+                                               GENERIC_EXECUTE);
+
+       if (with_write_flags && with_read_flags)
+               return SMBOPEN_READWRITE;
+       else if (with_write_flags)
                return SMBOPEN_WRITE;
-
-       /* just go for read/write */
-       return SMBOPEN_READWRITE;
+       else if (with_execute_flags)
+               return SMBOPEN_EXECUTE;
+       else
+               return SMBOPEN_READ;
 }
 
 int