aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2013-10-14 01:44:19 -0400
committerSteve French <smfrench@gmail.com>2013-10-28 10:21:36 -0400
commit7ff8d45c9dccf0744404d6fe44468ede7c1b9533 (patch)
treef5bbb545bd34b79d0cafa6a6680415e94c240c88
parent959f58544b7f20c92d5eb43d1232c96c15c01bfb (diff)
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>
-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 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,
1137 1137
1138 cifs_dbg(FYI, "SMB2 IOCTL\n"); 1138 cifs_dbg(FYI, "SMB2 IOCTL\n");
1139 1139
1140 *out_data = NULL;
1140 /* zero out returned data len, in case of error */ 1141 /* zero out returned data len, in case of error */
1141 if (plen) 1142 if (plen)
1142 *plen = 0; 1143 *plen = 0;
@@ -1182,11 +1183,23 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
1182 req->Flags = 0; 1183 req->Flags = 0;
1183 1184
1184 iov[0].iov_base = (char *)req; 1185 iov[0].iov_base = (char *)req;
1185 /* 4 for rfc1002 length field */
1186 iov[0].iov_len = get_rfc1002_length(req) + 4;
1187 1186
1188 if (indatalen) 1187 /*
1189 inc_rfc1001_len(req, indatalen); 1188 * If no input data, the size of ioctl struct in
1189 * protocol spec still includes a 1 byte data buffer,
1190 * but if input data passed to ioctl, we do not
1191 * want to double count this, so we do not send
1192 * the dummy one byte of data in iovec[0] if sending
1193 * input data (in iovec[1]). We also must add 4 bytes
1194 * in first iovec to allow for rfc1002 length field.
1195 */
1196
1197 if (indatalen) {
1198 iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
1199 inc_rfc1001_len(req, indatalen - 1);
1200 } else
1201 iov[0].iov_len = get_rfc1002_length(req) + 4;
1202
1190 1203
1191 rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0); 1204 rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
1192 rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base; 1205 rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;