summaryrefslogtreecommitdiff
path: root/fs/cifs/smb2misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2misc.c')
-rw-r--r--fs/cifs/smb2misc.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index 3d383489b9cf..fd516ea8b8f8 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -28,31 +28,32 @@
#include "cifs_debug.h"
#include "cifs_unicode.h"
#include "smb2status.h"
+#include "smb2glob.h"
static int
-check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
+check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
{
- __u64 wire_mid = le64_to_cpu(hdr->MessageId);
+ __u64 wire_mid = le64_to_cpu(shdr->MessageId);
/*
* Make sure that this really is an SMB, that it is a response,
* and that the message ids match.
*/
- if ((hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
+ if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
(mid == wire_mid)) {
- if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
+ if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
return 0;
else {
/* only one valid case where server sends us request */
- if (hdr->Command == SMB2_OPLOCK_BREAK)
+ if (shdr->Command == SMB2_OPLOCK_BREAK)
return 0;
else
cifs_dbg(VFS, "Received Request not response\n");
}
} else { /* bad signature or mid */
- if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
+ if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
cifs_dbg(VFS, "Bad protocol string signature header %x\n",
- le32_to_cpu(hdr->ProtocolId));
+ le32_to_cpu(shdr->ProtocolId));
if (mid != wire_mid)
cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
mid, wire_mid);
@@ -95,8 +96,9 @@ static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
int
smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
{
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
- struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
+ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+ struct smb2_hdr *hdr = &pdu->hdr;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
__u64 mid;
__u32 len = get_rfc1002_length(buf);
__u32 clc_len; /* calculated length */
@@ -111,7 +113,7 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
* ie Validate the wct via smb2_struct_sizes table above
*/
- if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+ if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
struct smb2_transform_hdr *thdr =
(struct smb2_transform_hdr *)buf;
struct cifs_ses *ses = NULL;
@@ -133,10 +135,10 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
}
}
-
- mid = le64_to_cpu(hdr->MessageId);
+ mid = le64_to_cpu(shdr->MessageId);
if (length < sizeof(struct smb2_pdu)) {
- if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
+ if ((length >= sizeof(struct smb2_hdr))
+ && (shdr->Status != 0)) {
pdu->StructureSize2 = 0;
/*
* As with SMB/CIFS, on some error cases servers may
@@ -154,29 +156,30 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
return 1;
}
- if (check_smb2_hdr(hdr, mid))
+ if (check_smb2_hdr(shdr, mid))
return 1;
- if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
+ if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
cifs_dbg(VFS, "Illegal structure size %u\n",
- le16_to_cpu(hdr->StructureSize));
+ le16_to_cpu(shdr->StructureSize));
return 1;
}
- command = le16_to_cpu(hdr->Command);
+ command = le16_to_cpu(shdr->Command);
if (command >= NUMBER_OF_SMB2_COMMANDS) {
cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
return 1;
}
if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
- if (command != SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0 ||
+ if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
/* error packets have 9 byte structure size */
cifs_dbg(VFS, "Illegal response size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command);
return 1;
- } else if (command == SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0)
+ } else if (command == SMB2_OPLOCK_BREAK_HE
+ && (shdr->Status == 0)
&& (le16_to_cpu(pdu->StructureSize2) != 44)
&& (le16_to_cpu(pdu->StructureSize2) != 36)) {
/* special case for SMB2.1 lease break message */
@@ -199,7 +202,7 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
clc_len, 4 + len, mid);
/* create failed on symlink */
if (command == SMB2_CREATE_HE &&
- hdr->Status == STATUS_STOPPED_ON_SYMLINK)
+ shdr->Status == STATUS_STOPPED_ON_SYMLINK)
return 0;
/* Windows 7 server returns 24 bytes more */
if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
@@ -261,11 +264,12 @@ static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
char *
smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
{
+ struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
*off = 0;
*len = 0;
/* error responses do not have data area */
- if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
+ if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
(((struct smb2_err_rsp *)hdr)->StructureSize) ==
SMB2_ERROR_STRUCTURE_SIZE2)
return NULL;
@@ -275,7 +279,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
* of the data buffer offset and data buffer length for the particular
* command.
*/
- switch (hdr->Command) {
+ switch (shdr->Command) {
case SMB2_NEGOTIATE:
*off = le16_to_cpu(
((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
@@ -346,7 +350,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
/* return pointer to beginning of data area, ie offset from SMB start */
if ((*off != 0) && (*len != 0))
- return (char *)(&hdr->ProtocolId) + *off;
+ return (char *)shdr + *off;
else
return NULL;
}
@@ -358,12 +362,13 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
unsigned int
smb2_calc_size(void *buf)
{
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
- struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
+ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+ struct smb2_hdr *hdr = &pdu->hdr;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
int offset; /* the offset from the beginning of SMB to data area */
int data_length; /* the length of the variable length data area */
/* Structure Size has already been checked to make sure it is 64 */
- int len = 4 + le16_to_cpu(pdu->hdr.StructureSize);
+ int len = 4 + le16_to_cpu(shdr->StructureSize);
/*
* StructureSize2, ie length of fixed parameter area has already
@@ -371,7 +376,7 @@ smb2_calc_size(void *buf)
*/
len += le16_to_cpu(pdu->StructureSize2);
- if (has_smb2_data_area[le16_to_cpu(hdr->Command)] == false)
+ if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false)
goto calc_size_exit;
smb2_get_data_area_len(&offset, &data_length, hdr);
@@ -582,7 +587,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
cifs_dbg(FYI, "Checking for oplock break\n");
- if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
+ if (rsp->hdr.sync_hdr.Command != SMB2_OPLOCK_BREAK)
return false;
if (rsp->StructureSize !=