aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/transport.c
diff options
context:
space:
mode:
authorPaulo Alcantara <paulo@paulo.ac>2018-06-15 10:22:44 -0300
committerSteve French <stfrench@microsoft.com>2018-06-15 19:17:40 -0500
commit35e2cc1ba755cf9dbd042e308b2928c868767a98 (patch)
tree7a4480897728404002b2a388f6f4245c902e90b4 /fs/cifs/transport.c
parentsmb3: fix corrupt path in subdirs on smb311 with posix (diff)
downloadlinux-dev-35e2cc1ba755cf9dbd042e308b2928c868767a98.tar.xz
linux-dev-35e2cc1ba755cf9dbd042e308b2928c868767a98.zip
cifs: Use correct packet length in SMB2_TRANSFORM header
In smb3_init_transform_rq(), 'orig_len' was only counting the request length, but forgot to count any data pages in the request. Writing or creating files with the 'seal' mount option was broken. In addition, do some code refactoring by exporting smb2_rqst_len() to calculate the appropriate packet size and avoid duplicating the same calculation all over the code. The start of the io vector is either the rfc1002 length (4 bytes) or a SMB2 header which is always > 4. Use this fact to check and skip the rfc1002 length if requested. Signed-off-by: Paulo Alcantara <palcantara@suse.de> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to '')
-rw-r--r--fs/cifs/transport.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index a3ea42a4cb98..fb57dfbfb749 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -201,15 +201,24 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
return 0;
}
-static unsigned long
-smb2_rqst_len(struct smb_rqst *rqst)
+unsigned long
+smb2_rqst_len(struct smb_rqst *rqst, bool skip_rfc1002_marker)
{
unsigned int i;
- struct kvec *iov = rqst->rq_iov;
+ struct kvec *iov;
+ int nvec;
unsigned long buflen = 0;
+ if (skip_rfc1002_marker && rqst->rq_iov[0].iov_len == 4) {
+ iov = &rqst->rq_iov[1];
+ nvec = rqst->rq_nvec - 1;
+ } else {
+ iov = rqst->rq_iov;
+ nvec = rqst->rq_nvec;
+ }
+
/* total up iov array first */
- for (i = 0; i < rqst->rq_nvec; i++)
+ for (i = 0; i < nvec; i++)
buflen += iov[i].iov_len;
/*
@@ -262,7 +271,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
(char *)&val, sizeof(val));
for (j = 0; j < num_rqst; j++)
- send_length += smb2_rqst_len(&rqst[j]);
+ send_length += smb2_rqst_len(&rqst[j], true);
rfc1002_marker = cpu_to_be32(send_length);
/* Generate a rfc1002 marker for SMB2+ */