Merge tag '4.16-minor-rc-SMB3-fixes' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 9 Feb 2018 22:42:57 +0000 (14:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 9 Feb 2018 22:42:57 +0000 (14:42 -0800)
Pull cifs fixes from Steve French:
 "There are a couple additional security fixes that are still being
  tested that are not in this set."

* tag '4.16-minor-rc-SMB3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  Add missing structs and defines from recent SMB3.1.1 documentation
  address lock imbalance warnings in smbdirect.c
  cifs: silence compiler warnings showing up with gcc-8.0.0
  Add some missing debug fields in server and tcon structs

fs/cifs/cifs_debug.c
fs/cifs/cifssmb.c
fs/cifs/smb2pdu.h
fs/cifs/smbdirect.c

index c7a863219fa36b77d9587d12a18aeca2cae1d52a..e35e711db68ecaad868efc4bf0815c139fa99129 100644 (file)
@@ -128,6 +128,10 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
                seq_puts(m, " type: CDROM ");
        else
                seq_printf(m, " type: %d ", dev_type);
+       if (tcon->seal)
+               seq_printf(m, " Encrypted");
+       if (tcon->unix_ext)
+               seq_printf(m, " POSIX Extensions");
        if (tcon->ses->server->ops->dump_share_caps)
                tcon->ses->server->ops->dump_share_caps(m, tcon);
 
@@ -246,7 +250,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
                        atomic_read(&server->smbd_conn->mr_used_count));
 skip_rdma:
 #endif
-               seq_printf(m, "\nNumber of credits: %d", server->credits);
+               seq_printf(m, "\nNumber of credits: %d Dialect 0x%x",
+                       server->credits,  server->dialect);
+               if (server->sign)
+                       seq_printf(m, " signed");
                i++;
                list_for_each(tmp2, &server->smb_ses_list) {
                        ses = list_entry(tmp2, struct cifs_ses,
index 4e0922d24eb216d3549e6a09958825de7616b51e..9ceebf30eb22e905303ad714b50150cbf16c7457 100644 (file)
@@ -6343,9 +6343,7 @@ SetEARetry:
        pSMB->InformationLevel =
                cpu_to_le16(SMB_SET_FILE_EA);
 
-       parm_data =
-               (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
-                                      offset);
+       parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
        pSMB->ParameterOffset = cpu_to_le16(param_offset);
        pSMB->DataOffset = cpu_to_le16(offset);
        pSMB->SetupCount = 1;
index 6eb9f9691ed409d2413e6ef5d535fd0ee36efd19..2a2b34ccaf492026d1a2e787836b6304ee3997dc 100644 (file)
@@ -192,6 +192,35 @@ struct smb2_symlink_err_rsp {
        __u8  PathBuffer[0];
 } __packed;
 
+/* SMB 3.1.1 and later dialects. See MS-SMB2 section 2.2.2.1 */
+struct smb2_error_context_rsp {
+       __le32 ErrorDataLength;
+       __le32 ErrorId;
+       __u8  ErrorContextData; /* ErrorDataLength long array */
+} __packed;
+
+/* Defines for Type field below (see MS-SMB2 2.2.2.2.2.1) */
+#define MOVE_DST_IPADDR_V4     cpu_to_le32(0x00000001)
+#define MOVE_DST_IPADDR_V6     cpu_to_le32(0x00000002)
+
+struct move_dst_ipaddr {
+       __le32 Type;
+       __u32  Reserved;
+       __u8   address[16]; /* IPv4 followed by 12 bytes rsvd or IPv6 address */
+} __packed;
+
+struct share_redirect_error_context_rsp {
+       __le32 StructureSize;
+       __le32 NotificationType;
+       __le32 ResourceNameOffset;
+       __le32 ResourceNameLength;
+       __le16 Flags;
+       __le16 TargetType;
+       __le32 IPAddrCount;
+       struct move_dst_ipaddr IpAddrMoveList[0];
+       /* __u8 ResourceName[] */ /* Name of share as counted Unicode string */
+} __packed;
+
 #define SMB2_CLIENT_GUID_SIZE 16
 
 struct smb2_negotiate_req {
@@ -320,7 +349,9 @@ struct smb2_logoff_rsp {
 } __packed;
 
 /* Flags/Reserved for SMB3.1.1 */
-#define SMB2_SHAREFLAG_CLUSTER_RECONNECT       0x0001
+#define SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT cpu_to_le16(0x0001)
+#define SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER cpu_to_le16(0x0002)
+#define SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT cpu_to_le16(0x0004)
 
 struct smb2_tree_connect_req {
        struct smb2_sync_hdr sync_hdr;
@@ -331,6 +362,82 @@ struct smb2_tree_connect_req {
        __u8   Buffer[1];       /* variable length */
 } __packed;
 
+/* See MS-SMB2 section 2.2.9.2 */
+/* Context Types */
+#define SMB2_RESERVED_TREE_CONNECT_CONTEXT_ID 0x0000
+#define SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID cpu_to_le16(0x0001)
+
+struct tree_connect_contexts {
+       __le16 ContextType;
+       __le16 DataLength;
+       __le32 Reserved;
+       __u8   Data[0];
+} __packed;
+
+/* Remoted identity tree connect context structures - see MS-SMB2 2.2.9.2.1 */
+struct smb3_blob_data {
+       __le16 BlobSize;
+       __u8   BlobData[0];
+} __packed;
+
+/* Valid values for Attr */
+#define SE_GROUP_MANDATORY             0x00000001
+#define SE_GROUP_ENABLED_BY_DEFAULT    0x00000002
+#define SE_GROUP_ENABLED               0x00000004
+#define SE_GROUP_OWNER                 0x00000008
+#define SE_GROUP_USE_FOR_DENY_ONLY     0x00000010
+#define SE_GROUP_INTEGRITY             0x00000020
+#define SE_GROUP_INTEGRITY_ENABLED     0x00000040
+#define SE_GROUP_RESOURCE              0x20000000
+#define SE_GROUP_LOGON_ID              0xC0000000
+
+/* struct sid_attr_data is SidData array in BlobData format then le32 Attr */
+
+struct sid_array_data {
+       __le16 SidAttrCount;
+       /* SidAttrList - array of sid_attr_data structs */
+} __packed;
+
+struct luid_attr_data {
+
+} __packed;
+
+/*
+ * struct privilege_data is the same as BLOB_DATA - see MS-SMB2 2.2.9.2.1.5
+ * but with size of LUID_ATTR_DATA struct and BlobData set to LUID_ATTR DATA
+ */
+
+struct privilege_array_data {
+       __le16 PrivilegeCount;
+       /* array of privilege_data structs */
+} __packed;
+
+struct remoted_identity_tcon_context {
+       __le16 TicketType; /* must be 0x0001 */
+       __le16 TicketSize; /* total size of this struct */
+       __le16 User; /* offset to SID_ATTR_DATA struct with user info */
+       __le16 UserName; /* offset to null terminated Unicode username string */
+       __le16 Domain; /* offset to null terminated Unicode domain name */
+       __le16 Groups; /* offset to SID_ARRAY_DATA struct with group info */
+       __le16 RestrictedGroups; /* similar to above */
+       __le16 Privileges; /* offset to PRIVILEGE_ARRAY_DATA struct */
+       __le16 PrimaryGroup; /* offset to SID_ARRAY_DATA struct */
+       __le16 Owner; /* offset to BLOB_DATA struct */
+       __le16 DefaultDacl; /* offset to BLOB_DATA struct */
+       __le16 DeviceGroups; /* offset to SID_ARRAY_DATA struct */
+       __le16 UserClaims; /* offset to BLOB_DATA struct */
+       __le16 DeviceClaims; /* offset to BLOB_DATA struct */
+       __u8   TicketInfo[0]; /* variable length buf - remoted identity data */
+} __packed;
+
+struct smb2_tree_connect_req_extension {
+       __le32 TreeConnectContextOffset;
+       __le16 TreeConnectContextCount;
+       __u8  Reserved[10];
+       __u8  PathName[0]; /* variable sized array */
+       /* followed by array of TreeConnectContexts */
+} __packed;
+
 struct smb2_tree_connect_rsp {
        struct smb2_hdr hdr;
        __le16 StructureSize;   /* Must be 16 */
@@ -365,7 +472,8 @@ struct smb2_tree_connect_rsp {
 #define SHI1005_FLAGS_ENABLE_HASH_V1                   0x00002000
 #define SHI1005_FLAGS_ENABLE_HASH_V2                   0x00004000
 #define SHI1005_FLAGS_ENCRYPT_DATA                     0x00008000
-#define SHI1005_FLAGS_ALL                              0x0000FF33
+#define SMB2_SHAREFLAG_IDENTITY_REMOTING               0x00040000 /* 3.1.1 */
+#define SHI1005_FLAGS_ALL                              0x0004FF33
 
 /* Possible share capabilities */
 #define SMB2_SHARE_CAP_DFS     cpu_to_le32(0x00000008) /* all dialects */
@@ -373,6 +481,7 @@ struct smb2_tree_connect_rsp {
 #define SMB2_SHARE_CAP_SCALEOUT        cpu_to_le32(0x00000020) /* 3.0 */
 #define SMB2_SHARE_CAP_CLUSTER cpu_to_le32(0x00000040) /* 3.0 */
 #define SMB2_SHARE_CAP_ASYMMETRIC cpu_to_le32(0x00000080) /* 3.02 */
+#define SMB2_SHARE_CAP_REDIRECT_TO_OWNER cpu_to_le32(0x00000100) /* 3.1.1 */
 
 struct smb2_tree_disconnect_req {
        struct smb2_sync_hdr sync_hdr;
@@ -556,6 +665,7 @@ struct create_context {
 #define SMB2_LEASE_WRITE_CACHING       cpu_to_le32(0x04)
 
 #define SMB2_LEASE_FLAG_BREAK_IN_PROGRESS cpu_to_le32(0x02)
+#define SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET cpu_to_le32(0x00000004)
 
 #define SMB2_LEASE_KEY_SIZE 16
 
index 5130492847eb15389757b550346ee6608ee76d9a..91710eb571fb3a61a1fe601d2eb72b0e7b15cc8a 100644 (file)
@@ -217,9 +217,10 @@ static void smbd_destroy_rdma_work(struct work_struct *work)
                        spin_unlock_irqrestore(
                                &info->reassembly_queue_lock, flags);
                        put_receive_buffer(info, response);
-               }
+               } else
+                       spin_unlock_irqrestore(&info->reassembly_queue_lock, flags);
        } while (response);
-       spin_unlock_irqrestore(&info->reassembly_queue_lock, flags);
+
        info->reassembly_data_length = 0;
 
        log_rdma_event(INFO, "free receive buffers\n");
@@ -1934,15 +1935,16 @@ again:
                                 * No need to lock if we are not at the
                                 * end of the queue
                                 */
-                               if (!queue_length)
+                               if (queue_length)
+                                       list_del(&response->list);
+                               else {
                                        spin_lock_irq(
                                                &info->reassembly_queue_lock);
-                               list_del(&response->list);
-                               queue_removed++;
-                               if (!queue_length)
+                                       list_del(&response->list);
                                        spin_unlock_irq(
                                                &info->reassembly_queue_lock);
-
+                               }
+                               queue_removed++;
                                info->count_reassembly_queue--;
                                info->count_dequeue_reassembly_queue++;
                                put_receive_buffer(info, response);