diff options
| author | Steve French <smfrench@gmail.com> | 2013-10-14 01:44:19 -0400 |
|---|---|---|
| committer | Steve French <smfrench@gmail.com> | 2013-10-28 10:21:36 -0400 |
| commit | 7ff8d45c9dccf0744404d6fe44468ede7c1b9533 (patch) | |
| tree | f5bbb545bd34b79d0cafa6a6680415e94c240c88 /fs/cifs | |
| parent | 959f58544b7f20c92d5eb43d1232c96c15c01bfb (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>
Diffstat (limited to 'fs/cifs')
| -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, | |||
| 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; |
