summaryrefslogtreecommitdiff
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2013-10-14 00:44:19 -0500
committerJiri Slaby <jslaby@suse.cz>2015-06-02 12:34:12 +0200
commita8484fc37ca4d536e5327c6fc9072e4be40ac014 (patch)
treee3b7c4f88a2fd08394336e4742092baef3423e7b /fs/cifs
parent266ed50f2a81a882d54c4ff7452bca370f396bae (diff)
Fix corrupt SMB2 ioctl requests
commit 7ff8d45c9dccf0744404d6fe44468ede7c1b9533 upstream. We were off by one calculating the length of ioctls in some cases because the protocol specification for SMB2 ioctl includes a mininum one byte payload but not all SMB2 ioctl requests actually have a data buffer to send. We were also not zeroing out the return buffer (in case of error this is helpful). Signed-off-by: Steve French <smfrench@gmail.com> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/smb2pdu.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 1f096f694030..1bf0ba805ef5 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1228,6 +1228,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
cifs_dbg(FYI, "SMB2 IOCTL\n");
+ *out_data = NULL;
/* zero out returned data len, in case of error */
if (plen)
*plen = 0;
@@ -1273,11 +1274,23 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
req->Flags = 0;
iov[0].iov_base = (char *)req;
- /* 4 for rfc1002 length field */
- iov[0].iov_len = get_rfc1002_length(req) + 4;
- if (indatalen)
- inc_rfc1001_len(req, indatalen);
+ /*
+ * If no input data, the size of ioctl struct in
+ * protocol spec still includes a 1 byte data buffer,
+ * but if input data passed to ioctl, we do not
+ * want to double count this, so we do not send
+ * the dummy one byte of data in iovec[0] if sending
+ * input data (in iovec[1]). We also must add 4 bytes
+ * in first iovec to allow for rfc1002 length field.
+ */
+
+ if (indatalen) {
+ iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
+ inc_rfc1001_len(req, indatalen - 1);
+ } else
+ iov[0].iov_len = get_rfc1002_length(req) + 4;
+
rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;