Merge tag '6.7-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 4 Nov 2023 19:13:50 +0000 (09:13 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 4 Nov 2023 19:13:50 +0000 (09:13 -1000)
Pull smb client updates from Steve French:

 - use after free fixes and deadlock fix

 - symlink timestamp fix

 - hashing perf improvement

 - multichannel fixes

 - minor debugging improvements

 - fix creating fifos when using "sfu" mounts

 - NTLMSSP authentication improvement

 - minor fixes to include some missing create flags and structures from
   recently updated protocol documentation

* tag '6.7-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: force interface update before a fresh session setup
  cifs: do not reset chan_max if multichannel is not supported at mount
  cifs: reconnect helper should set reconnect for the right channel
  smb: client: fix use-after-free in smb2_query_info_compound()
  smb: client: remove extra @chan_count check in __cifs_put_smb_ses()
  cifs: add xid to query server interface call
  cifs: print server capabilities in DebugData
  smb: use crypto_shash_digest() in symlink_hash()
  smb: client: fix use-after-free bug in cifs_debug_data_proc_show()
  smb: client: fix potential deadlock when releasing mids
  smb3: fix creating FIFOs when mounting with "sfu" mount option
  Add definition for new smb3.1.1 command type
  SMB3: clarify some of the unused CreateOption flags
  cifs: Add client version details to NTLM authenticate message
  smb3: fix touch -h of symlink

14 files changed:
fs/smb/client/cached_dir.c
fs/smb/client/cifs_debug.c
fs/smb/client/cifsfs.c
fs/smb/client/cifspdu.h
fs/smb/client/cifsproto.h
fs/smb/client/connect.c
fs/smb/client/inode.c
fs/smb/client/link.c
fs/smb/client/ntlmssp.h
fs/smb/client/sess.c
fs/smb/client/smb2misc.c
fs/smb/client/smb2ops.c
fs/smb/client/transport.c
fs/smb/common/smb2pdu.h

index fe1bf5b..59f6b8e 100644 (file)
@@ -32,7 +32,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
                         * fully cached or it may be in the process of
                         * being deleted due to a lease break.
                         */
-                       if (!cfid->has_lease) {
+                       if (!cfid->time || !cfid->has_lease) {
                                spin_unlock(&cfids->cfid_list_lock);
                                return NULL;
                        }
@@ -193,10 +193,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        npath = path_no_prefix(cifs_sb, path);
        if (IS_ERR(npath)) {
                rc = PTR_ERR(npath);
-               kfree(utf16_path);
-               return rc;
+               goto out;
        }
 
+       if (!npath[0]) {
+               dentry = dget(cifs_sb->root);
+       } else {
+               dentry = path_to_dentry(cifs_sb, npath);
+               if (IS_ERR(dentry)) {
+                       rc = -ENOENT;
+                       goto out;
+               }
+       }
+       cfid->dentry = dentry;
+
        /*
         * We do not hold the lock for the open because in case
         * SMB2_open needs to reconnect.
@@ -249,6 +259,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 
        smb2_set_related(&rqst[1]);
 
+       /*
+        * Set @cfid->has_lease to true before sending out compounded request so
+        * its lease reference can be put in cached_dir_lease_break() due to a
+        * potential lease break right after the request is sent or while @cfid
+        * is still being cached.  Concurrent processes won't be to use it yet
+        * due to @cfid->time being zero.
+        */
+       cfid->has_lease = true;
+
        rc = compound_send_recv(xid, ses, server,
                                flags, 2, rqst,
                                resp_buftype, rsp_iov);
@@ -263,6 +282,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        cfid->tcon = tcon;
        cfid->is_open = true;
 
+       spin_lock(&cfids->cfid_list_lock);
+
        o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
        oparms.fid->persistent_fid = o_rsp->PersistentFileId;
        oparms.fid->volatile_fid = o_rsp->VolatileFileId;
@@ -270,18 +291,25 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
 #endif /* CIFS_DEBUG2 */
 
-       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
+       rc = -EINVAL;
+       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
+               spin_unlock(&cfids->cfid_list_lock);
                goto oshr_free;
+       }
 
        smb2_parse_contexts(server, o_rsp,
                            &oparms.fid->epoch,
                            oparms.fid->lease_key, &oplock,
                            NULL, NULL);
-       if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
+       if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) {
+               spin_unlock(&cfids->cfid_list_lock);
                goto oshr_free;
+       }
        qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
-       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
+       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) {
+               spin_unlock(&cfids->cfid_list_lock);
                goto oshr_free;
+       }
        if (!smb2_validate_and_copy_iov(
                                le16_to_cpu(qi_rsp->OutputBufferOffset),
                                sizeof(struct smb2_file_all_info),
@@ -289,37 +317,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
                                (char *)&cfid->file_all_info))
                cfid->file_all_info_is_valid = true;
 
-       if (!npath[0])
-               dentry = dget(cifs_sb->root);
-       else {
-               dentry = path_to_dentry(cifs_sb, npath);
-               if (IS_ERR(dentry)) {
-                       rc = -ENOENT;
-                       goto oshr_free;
-               }
-       }
-       spin_lock(&cfids->cfid_list_lock);
-       cfid->dentry = dentry;
        cfid->time = jiffies;
-       cfid->has_lease = true;
        spin_unlock(&cfids->cfid_list_lock);
+       /* At this point the directory handle is fully cached */
+       rc = 0;
 
 oshr_free:
-       kfree(utf16_path);
        SMB2_open_free(&rqst[0]);
        SMB2_query_info_free(&rqst[1]);
        free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
        free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
-       spin_lock(&cfids->cfid_list_lock);
-       if (!cfid->has_lease) {
-               if (rc) {
-                       if (cfid->on_list) {
-                               list_del(&cfid->entry);
-                               cfid->on_list = false;
-                               cfids->num_entries--;
-                       }
-                       rc = -ENOENT;
-               } else {
+       if (rc) {
+               spin_lock(&cfids->cfid_list_lock);
+               if (cfid->on_list) {
+                       list_del(&cfid->entry);
+                       cfid->on_list = false;
+                       cfids->num_entries--;
+               }
+               if (cfid->has_lease) {
                        /*
                         * We are guaranteed to have two references at this
                         * point. One for the caller and one for a potential
@@ -327,25 +342,24 @@ oshr_free:
                         * will be closed when the caller closes the cached
                         * handle.
                         */
+                       cfid->has_lease = false;
                        spin_unlock(&cfids->cfid_list_lock);
                        kref_put(&cfid->refcount, smb2_close_cached_fid);
                        goto out;
                }
+               spin_unlock(&cfids->cfid_list_lock);
        }
-       spin_unlock(&cfids->cfid_list_lock);
+out:
        if (rc) {
                if (cfid->is_open)
                        SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
                                   cfid->fid.volatile_fid);
                free_cached_dir(cfid);
-               cfid = NULL;
-       }
-out:
-       if (rc == 0) {
+       } else {
                *ret_cfid = cfid;
                atomic_inc(&tcon->num_remote_opens);
        }
-
+       kfree(utf16_path);
        return rc;
 }
 
index 76922fc..6d8804f 100644 (file)
@@ -427,6 +427,8 @@ skip_rdma:
                if (server->nosharesock)
                        seq_printf(m, " nosharesock");
 
+               seq_printf(m, "\nServer capabilities: 0x%x", server->capabilities);
+
                if (server->rdma)
                        seq_printf(m, "\nRDMA ");
                seq_printf(m, "\nTCP status: %d Instance: %d"
@@ -452,6 +454,11 @@ skip_rdma:
                seq_printf(m, "\n\n\tSessions: ");
                i = 0;
                list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+                       spin_lock(&ses->ses_lock);
+                       if (ses->ses_status == SES_EXITING) {
+                               spin_unlock(&ses->ses_lock);
+                               continue;
+                       }
                        i++;
                        if ((ses->serverDomain == NULL) ||
                                (ses->serverOS == NULL) ||
@@ -472,6 +479,7 @@ skip_rdma:
                                ses->ses_count, ses->serverOS, ses->serverNOS,
                                ses->capabilities, ses->ses_status);
                        }
+                       spin_unlock(&ses->ses_lock);
 
                        seq_printf(m, "\n\tSecurity type: %s ",
                                get_security_type_str(server->ops->select_sectype(server, ses->sectype)));
index 22869cd..ea3a7a6 100644 (file)
@@ -1191,6 +1191,7 @@ const char *cifs_get_link(struct dentry *dentry, struct inode *inode,
 
 const struct inode_operations cifs_symlink_inode_ops = {
        .get_link = cifs_get_link,
+       .setattr = cifs_setattr,
        .permission = cifs_permission,
        .listxattr = cifs_listxattr,
 };
index e17222f..a75220d 100644 (file)
@@ -2570,7 +2570,7 @@ typedef struct {
 
 
 struct win_dev {
-       unsigned char type[8]; /* IntxCHR or IntxBLK */
+       unsigned char type[8]; /* IntxCHR or IntxBLK or LnxFIFO*/
        __le64 major;
        __le64 minor;
 } __attribute__((packed));
index 0c37eef..890cedd 100644 (file)
@@ -81,7 +81,7 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 char *cifs_build_devname(char *nodename, const char *prepath);
 extern void delete_mid(struct mid_q_entry *mid);
-extern void release_mid(struct mid_q_entry *mid);
+void __release_mid(struct kref *refcount);
 extern void cifs_wake_up_task(struct mid_q_entry *mid);
 extern int cifs_handle_standard(struct TCP_Server_Info *server,
                                struct mid_q_entry *mid);
@@ -740,4 +740,9 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
        return true;
 }
 
+static inline void release_mid(struct mid_q_entry *mid)
+{
+       kref_put(&mid->refcount, __release_mid);
+}
+
 #endif                 /* _CIFSPROTO_H */
index 7b923e3..1a137b3 100644 (file)
@@ -119,6 +119,7 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
 static void smb2_query_server_interfaces(struct work_struct *work)
 {
        int rc;
+       int xid;
        struct cifs_tcon *tcon = container_of(work,
                                        struct cifs_tcon,
                                        query_interfaces.work);
@@ -126,7 +127,10 @@ static void smb2_query_server_interfaces(struct work_struct *work)
        /*
         * query server network interfaces, in case they change
         */
-       rc = SMB3_request_interfaces(0, tcon, false);
+       xid = get_xid();
+       rc = SMB3_request_interfaces(xid, tcon, false);
+       free_xid(xid);
+
        if (rc) {
                cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
                                __func__, rc);
@@ -156,13 +160,14 @@ cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
        /* If server is a channel, select the primary channel */
        pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
 
-       spin_lock(&pserver->srv_lock);
+       /* if we need to signal just this channel */
        if (!all_channels) {
-               pserver->tcpStatus = CifsNeedReconnect;
-               spin_unlock(&pserver->srv_lock);
+               spin_lock(&server->srv_lock);
+               if (server->tcpStatus != CifsExiting)
+                       server->tcpStatus = CifsNeedReconnect;
+               spin_unlock(&server->srv_lock);
                return;
        }
-       spin_unlock(&pserver->srv_lock);
 
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
@@ -1969,9 +1974,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
 
 void __cifs_put_smb_ses(struct cifs_ses *ses)
 {
-       unsigned int rc, xid;
-       unsigned int chan_count;
        struct TCP_Server_Info *server = ses->server;
+       unsigned int xid;
+       size_t i;
+       int rc;
 
        spin_lock(&ses->ses_lock);
        if (ses->ses_status == SES_EXITING) {
@@ -2017,20 +2023,14 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
        list_del_init(&ses->smb_ses_list);
        spin_unlock(&cifs_tcp_ses_lock);
 
-       chan_count = ses->chan_count;
-
        /* close any extra channels */
-       if (chan_count > 1) {
-               int i;
-
-               for (i = 1; i < chan_count; i++) {
-                       if (ses->chans[i].iface) {
-                               kref_put(&ses->chans[i].iface->refcount, release_iface);
-                               ses->chans[i].iface = NULL;
-                       }
-                       cifs_put_tcp_session(ses->chans[i].server, 0);
-                       ses->chans[i].server = NULL;
+       for (i = 1; i < ses->chan_count; i++) {
+               if (ses->chans[i].iface) {
+                       kref_put(&ses->chans[i].iface->refcount, release_iface);
+                       ses->chans[i].iface = NULL;
                }
+               cifs_put_tcp_session(ses->chans[i].server, 0);
+               ses->chans[i].server = NULL;
        }
 
        sesInfoFree(ses);
@@ -3849,8 +3849,12 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
        is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
        spin_unlock(&ses->chan_lock);
 
-       if (!is_binding)
+       if (!is_binding) {
                ses->ses_status = SES_IN_SETUP;
+
+               /* force iface_list refresh */
+               ses->iface_last_update = 0;
+       }
        spin_unlock(&ses->ses_lock);
 
        /* update ses ip_addr only for primary chan */
index 3abfe77..86fbd3f 100644 (file)
@@ -594,6 +594,10 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
                        cifs_dbg(FYI, "Symlink\n");
                        fattr->cf_mode |= S_IFLNK;
                        fattr->cf_dtype = DT_LNK;
+               } else if (memcmp("LnxFIFO", pbuf, 8) == 0) {
+                       cifs_dbg(FYI, "FIFO\n");
+                       fattr->cf_mode |= S_IFIFO;
+                       fattr->cf_dtype = DT_FIFO;
                } else {
                        fattr->cf_mode |= S_IFREG; /* file? */
                        fattr->cf_dtype = DT_REG;
index c66be49..a1da50e 100644 (file)
@@ -42,23 +42,11 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
 
        rc = cifs_alloc_hash("md5", &md5);
        if (rc)
-               goto symlink_hash_err;
+               return rc;
 
-       rc = crypto_shash_init(md5);
-       if (rc) {
-               cifs_dbg(VFS, "%s: Could not init md5 shash\n", __func__);
-               goto symlink_hash_err;
-       }
-       rc = crypto_shash_update(md5, link_str, link_len);
-       if (rc) {
-               cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__);
-               goto symlink_hash_err;
-       }
-       rc = crypto_shash_final(md5, md5_hash);
+       rc = crypto_shash_digest(md5, link_str, link_len, md5_hash);
        if (rc)
                cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
-
-symlink_hash_err:
        cifs_free_hash(&md5);
        return rc;
 }
index 2c5dde2..875de43 100644 (file)
@@ -133,8 +133,8 @@ typedef struct _AUTHENTICATE_MESSAGE {
        SECURITY_BUFFER WorkstationName;
        SECURITY_BUFFER SessionKey;
        __le32 NegotiateFlags;
-       /* SECURITY_BUFFER for version info not present since we
-          do not set the version is present flag */
+       struct  ntlmssp_version Version;
+       /* SECURITY_BUFFER */
        char UserString[];
 } __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
 
index 79f26c5..cd474cf 100644 (file)
@@ -186,7 +186,6 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
        }
 
        if (!(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
-               ses->chan_max = 1;
                spin_unlock(&ses->chan_lock);
                cifs_server_dbg(VFS, "no multichannel support\n");
                return 0;
@@ -1060,10 +1059,16 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
        sec_blob->MessageType = NtLmAuthenticate;
 
+       /* send version information in ntlmssp authenticate also */
        flags = ses->ntlmssp->server_flags | NTLMSSP_REQUEST_TARGET |
-               NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
-       /* we only send version information in ntlmssp negotiate, so do not set this flag */
-       flags = flags & ~NTLMSSP_NEGOTIATE_VERSION;
+               NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_VERSION |
+               NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
+
+       sec_blob->Version.ProductMajorVersion = LINUX_VERSION_MAJOR;
+       sec_blob->Version.ProductMinorVersion = LINUX_VERSION_PATCHLEVEL;
+       sec_blob->Version.ProductBuild = cpu_to_le16(SMB3_PRODUCT_BUILD);
+       sec_blob->Version.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
+
        tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
        sec_blob->NegotiateFlags = cpu_to_le32(flags);
 
index 25f7cd6..32dfa0f 100644 (file)
@@ -787,7 +787,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
 {
        struct close_cancelled_open *cancelled;
 
-       cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
+       cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
        if (!cancelled)
                return -ENOMEM;
 
index f4849a8..601e7a1 100644 (file)
@@ -5089,7 +5089,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
         * over SMB2/SMB3 and Samba will do this with SMB3.1.1 POSIX Extensions
         */
 
-       if (!S_ISCHR(mode) && !S_ISBLK(mode))
+       if (!S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode))
                return rc;
 
        cifs_dbg(FYI, "sfu compat create special file\n");
@@ -5137,6 +5137,12 @@ smb2_make_node(unsigned int xid, struct inode *inode,
                pdev->minor = cpu_to_le64(MINOR(dev));
                rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
                                                        &bytes_written, iov, 1);
+       } else if (S_ISFIFO(mode)) {
+               memcpy(pdev->type, "LnxFIFO", 8);
+               pdev->major = 0;
+               pdev->minor = 0;
+               rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
+                                                       &bytes_written, iov, 1);
        }
        tcon->ses->server->ops->close(xid, tcon, &fid);
        d_drop(dentry);
index 14710af..d553b7a 100644 (file)
@@ -76,7 +76,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
        return temp;
 }
 
-static void __release_mid(struct kref *refcount)
+void __release_mid(struct kref *refcount)
 {
        struct mid_q_entry *midEntry =
                        container_of(refcount, struct mid_q_entry, refcount);
@@ -156,15 +156,6 @@ static void __release_mid(struct kref *refcount)
        mempool_free(midEntry, cifs_mid_poolp);
 }
 
-void release_mid(struct mid_q_entry *mid)
-{
-       struct TCP_Server_Info *server = mid->server;
-
-       spin_lock(&server->mid_lock);
-       kref_put(&mid->refcount, __release_mid);
-       spin_unlock(&server->mid_lock);
-}
-
 void
 delete_mid(struct mid_q_entry *mid)
 {
index 319fb9f..8983f45 100644 (file)
@@ -34,6 +34,7 @@
 #define SMB2_QUERY_INFO_HE     0x0010
 #define SMB2_SET_INFO_HE       0x0011
 #define SMB2_OPLOCK_BREAK_HE   0x0012
+#define SMB2_SERVER_TO_CLIENT_NOTIFICATION 0x0013
 
 /* The same list in little endian */
 #define SMB2_NEGOTIATE         cpu_to_le16(SMB2_NEGOTIATE_HE)
@@ -411,6 +412,7 @@ struct smb2_tree_disconnect_rsp {
 #define SMB2_GLOBAL_CAP_PERSISTENT_HANDLES 0x00000010 /* New to SMB3 */
 #define SMB2_GLOBAL_CAP_DIRECTORY_LEASING  0x00000020 /* New to SMB3 */
 #define SMB2_GLOBAL_CAP_ENCRYPTION     0x00000040 /* New to SMB3 */
+#define SMB2_GLOBAL_CAP_NOTIFICATIONS  0x00000080 /* New to SMB3.1.1 */
 /* Internal types */
 #define SMB2_NT_FIND                   0x00100000
 #define SMB2_LARGE_FILES               0x00200000
@@ -981,6 +983,19 @@ struct smb2_change_notify_rsp {
        __u8    Buffer[]; /* array of file notify structs */
 } __packed;
 
+/*
+ * SMB2_SERVER_TO_CLIENT_NOTIFICATION: See MS-SMB2 section 2.2.44
+ */
+
+#define SMB2_NOTIFY_SESSION_CLOSED     0x0000
+
+struct smb2_server_client_notification {
+       struct smb2_hdr hdr;
+       __le16  StructureSize;
+       __u16   Reserved; /* MBZ */
+       __le32  NotificationType;
+       __u8    NotificationBuffer[4]; /* MBZ */
+} __packed;
 
 /*
  * SMB2_CREATE  See MS-SMB2 section 2.2.13
@@ -1097,16 +1112,23 @@ struct smb2_change_notify_rsp {
 #define FILE_WRITE_THROUGH_LE          cpu_to_le32(0x00000002)
 #define FILE_SEQUENTIAL_ONLY_LE                cpu_to_le32(0x00000004)
 #define FILE_NO_INTERMEDIATE_BUFFERING_LE cpu_to_le32(0x00000008)
+/* FILE_SYNCHRONOUS_IO_ALERT_LE                cpu_to_le32(0x00000010) should be zero, ignored */
+/* FILE_SYNCHRONOUS_IO_NONALERT                cpu_to_le32(0x00000020) should be zero, ignored */
 #define FILE_NON_DIRECTORY_FILE_LE     cpu_to_le32(0x00000040)
 #define FILE_COMPLETE_IF_OPLOCKED_LE   cpu_to_le32(0x00000100)
 #define FILE_NO_EA_KNOWLEDGE_LE                cpu_to_le32(0x00000200)
+/* FILE_OPEN_REMOTE_INSTANCE           cpu_to_le32(0x00000400) should be zero, ignored */
 #define FILE_RANDOM_ACCESS_LE          cpu_to_le32(0x00000800)
-#define FILE_DELETE_ON_CLOSE_LE                cpu_to_le32(0x00001000)
+#define FILE_DELETE_ON_CLOSE_LE                cpu_to_le32(0x00001000) /* MBZ */
 #define FILE_OPEN_BY_FILE_ID_LE                cpu_to_le32(0x00002000)
 #define FILE_OPEN_FOR_BACKUP_INTENT_LE cpu_to_le32(0x00004000)
 #define FILE_NO_COMPRESSION_LE         cpu_to_le32(0x00008000)
+/* FILE_OPEN_REQUIRING_OPLOCK          cpu_to_le32(0x00010000) should be zero, ignored */
+/* FILE_DISALLOW_EXCLUSIVE             cpu_to_le32(0x00020000) should be zero, ignored */
+/* FILE_RESERVE_OPFILTER               cpu_to_le32(0x00100000) MBZ */
 #define FILE_OPEN_REPARSE_POINT_LE     cpu_to_le32(0x00200000)
 #define FILE_OPEN_NO_RECALL_LE         cpu_to_le32(0x00400000)
+/* #define FILE_OPEN_FOR_FREE_SPACE_QUERY cpu_to_le32(0x00800000) should be zero, ignored */
 #define CREATE_OPTIONS_MASK_LE          cpu_to_le32(0x00FFFFFF)
 
 #define FILE_READ_RIGHTS_LE (FILE_READ_DATA_LE | FILE_READ_EA_LE \