diff options
| -rw-r--r-- | fs/cifs/cifssmb.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 39cec0d9cd1b..675041a6949c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -331,31 +331,33 @@ smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
| 331 | 331 | ||
| 332 | static int validate_t2(struct smb_t2_rsp *pSMB) | 332 | static int validate_t2(struct smb_t2_rsp *pSMB) |
| 333 | { | 333 | { |
| 334 | int rc = -EINVAL; | 334 | unsigned int total_size; |
| 335 | int total_size; | 335 | |
| 336 | /* check for plausible wct */ | ||
| 337 | if (pSMB->hdr.WordCount < 10) | ||
| 338 | goto vt2_err; | ||
| 336 | 339 | ||
| 337 | /* check for plausible wct, bcc and t2 data and parm sizes */ | ||
| 338 | /* check for parm and data offset going beyond end of smb */ | 340 | /* check for parm and data offset going beyond end of smb */ |
| 339 | if (pSMB->hdr.WordCount >= 10) { | 341 | if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 || |
| 340 | if ((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) && | 342 | get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024) |
| 341 | (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) { | 343 | goto vt2_err; |
| 342 | /* check that bcc is at least as big as parms + data */ | 344 | |
| 343 | /* check that bcc is less than negotiated smb buffer */ | 345 | /* check that bcc is at least as big as parms + data */ |
| 344 | total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount); | 346 | /* check that bcc is less than negotiated smb buffer */ |
| 345 | if (total_size < 512) { | 347 | total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount); |
| 346 | total_size += | 348 | if (total_size >= 512) |
| 347 | le16_to_cpu(pSMB->t2_rsp.DataCount); | 349 | goto vt2_err; |
| 348 | if (total_size <= get_bcc(&pSMB->hdr) && | 350 | |
| 349 | total_size < | 351 | total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount); |
| 350 | CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 352 | if (total_size > get_bcc(&pSMB->hdr) || |
| 351 | return 0; | 353 | total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) |
| 352 | } | 354 | goto vt2_err; |
| 353 | } | 355 | |
| 354 | } | 356 | return 0; |
| 355 | } | 357 | vt2_err: |
| 356 | cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB, | 358 | cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB, |
| 357 | sizeof(struct smb_t2_rsp) + 16); | 359 | sizeof(struct smb_t2_rsp) + 16); |
| 358 | return rc; | 360 | return -EINVAL; |
| 359 | } | 361 | } |
| 360 | 362 | ||
| 361 | int | 363 | int |
