diff options
author | Steve French <smfrench@gmail.com> | 2013-10-14 00:44:19 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-10-28 09:21:36 -0500 |
commit | 7ff8d45c9dccf0744404d6fe44468ede7c1b9533 (patch) | |
tree | f5bbb545bd34b79d0cafa6a6680415e94c240c88 /fs | |
parent | 959f58544b7f20c92d5eb43d1232c96c15c01bfb (diff) | |
download | linux-stable-7ff8d45c9dccf0744404d6fe44468ede7c1b9533.tar.gz linux-stable-7ff8d45c9dccf0744404d6fe44468ede7c1b9533.tar.bz2 linux-stable-7ff8d45c9dccf0744404d6fe44468ede7c1b9533.zip |
Fix corrupt SMB2 ioctl requests
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/smb2pdu.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index edccb5252462..6e1868611233 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1137,6 +1137,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; @@ -1182,11 +1183,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; |