|
Lines 588-595
Link Here
|
| 588 |
data_count = WVAL(inbuf, smb_drcnt); |
588 |
data_count = WVAL(inbuf, smb_drcnt); |
| 589 |
|
589 |
|
| 590 |
/* Modify offset for the split header/buffer we use */ |
590 |
/* Modify offset for the split header/buffer we use */ |
|
|
591 |
if (data_count || data_offset) { |
| 592 |
if (unlikely(data_offset < hdrlen)) |
| 593 |
goto out_bad_data; |
| 594 |
else |
| 591 |
data_offset -= hdrlen; |
595 |
data_offset -= hdrlen; |
|
|
596 |
} |
| 597 |
if (parm_count || parm_offset) { |
| 598 |
if (unlikely(parm_offset < hdrlen)) |
| 599 |
goto out_bad_parm; |
| 600 |
else |
| 592 |
parm_offset -= hdrlen; |
601 |
parm_offset -= hdrlen; |
|
|
602 |
} |
| 593 |
|
603 |
|
| 594 |
if (parm_count == parm_tot && data_count == data_tot) { |
604 |
if (parm_count == parm_tot && data_count == data_tot) { |
| 595 |
/* |
605 |
/* |
|
Lines 600-617
Link Here
|
| 600 |
* response that fits. |
610 |
* response that fits. |
| 601 |
*/ |
611 |
*/ |
| 602 |
VERBOSE("single trans2 response " |
612 |
VERBOSE("single trans2 response " |
| 603 |
"dcnt=%d, pcnt=%d, doff=%d, poff=%d\n", |
613 |
"dcnt=%u, pcnt=%u, doff=%u, poff=%u\n", |
| 604 |
data_count, parm_count, |
614 |
data_count, parm_count, |
| 605 |
data_offset, parm_offset); |
615 |
data_offset, parm_offset); |
| 606 |
req->rq_ldata = data_count; |
616 |
req->rq_ldata = data_count; |
| 607 |
req->rq_lparm = parm_count; |
617 |
req->rq_lparm = parm_count; |
| 608 |
req->rq_data = req->rq_buffer + data_offset; |
618 |
req->rq_data = req->rq_buffer + data_offset; |
| 609 |
req->rq_parm = req->rq_buffer + parm_offset; |
619 |
req->rq_parm = req->rq_buffer + parm_offset; |
|
|
620 |
if (unlikely(parm_offset + parm_count > req->rq_rlen)) |
| 621 |
goto out_bad_parm; |
| 622 |
if (unlikely(data_offset + data_count > req->rq_rlen)) |
| 623 |
goto out_bad_data; |
| 610 |
return 0; |
624 |
return 0; |
| 611 |
} |
625 |
} |
| 612 |
|
626 |
|
| 613 |
VERBOSE("multi trans2 response " |
627 |
VERBOSE("multi trans2 response " |
| 614 |
"frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n", |
628 |
"frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n", |
| 615 |
req->rq_fragment, |
629 |
req->rq_fragment, |
| 616 |
data_count, parm_count, |
630 |
data_count, parm_count, |
| 617 |
data_offset, parm_offset); |
631 |
data_offset, parm_offset); |
|
Lines 634-649
Link Here
|
| 634 |
req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS); |
648 |
req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS); |
| 635 |
if (!req->rq_trans2buffer) |
649 |
if (!req->rq_trans2buffer) |
| 636 |
goto out_no_mem; |
650 |
goto out_no_mem; |
|
|
651 |
memset(req->rq_trans2buffer, 0, buf_len); |
| 637 |
|
652 |
|
| 638 |
req->rq_parm = req->rq_trans2buffer; |
653 |
req->rq_parm = req->rq_trans2buffer; |
| 639 |
req->rq_data = req->rq_trans2buffer + parm_tot; |
654 |
req->rq_data = req->rq_trans2buffer + parm_tot; |
| 640 |
} else if (req->rq_total_data < data_tot || |
655 |
} else if (unlikely(req->rq_total_data < data_tot || |
| 641 |
req->rq_total_parm < parm_tot) |
656 |
req->rq_total_parm < parm_tot)) |
| 642 |
goto out_data_grew; |
657 |
goto out_data_grew; |
| 643 |
|
658 |
|
| 644 |
if (parm_disp + parm_count > req->rq_total_parm) |
659 |
if (unlikely(parm_disp + parm_count > req->rq_total_parm || |
|
|
660 |
parm_offset + parm_count > req->rq_rlen)) |
| 645 |
goto out_bad_parm; |
661 |
goto out_bad_parm; |
| 646 |
if (data_disp + data_count > req->rq_total_data) |
662 |
if (unlikely(data_disp + data_count > req->rq_total_data || |
|
|
663 |
data_offset + data_count > req->rq_rlen)) |
| 647 |
goto out_bad_data; |
664 |
goto out_bad_data; |
| 648 |
|
665 |
|
| 649 |
inbuf = req->rq_buffer; |
666 |
inbuf = req->rq_buffer; |
|
Lines 657-671
Link Here
|
| 657 |
* Check whether we've received all of the data. Note that |
674 |
* Check whether we've received all of the data. Note that |
| 658 |
* we use the packet totals -- total lengths might shrink! |
675 |
* we use the packet totals -- total lengths might shrink! |
| 659 |
*/ |
676 |
*/ |
| 660 |
if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) |
677 |
if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) { |
|
|
678 |
req->rq_ldata = data_tot; |
| 679 |
req->rq_lparm = parm_tot; |
| 661 |
return 0; |
680 |
return 0; |
|
|
681 |
} |
| 662 |
return 1; |
682 |
return 1; |
| 663 |
|
683 |
|
| 664 |
out_too_long: |
684 |
out_too_long: |
| 665 |
printk(KERN_ERR "smb_trans2: data/param too long, data=%d, parm=%d\n", |
685 |
printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n", |
| 666 |
data_tot, parm_tot); |
686 |
data_tot, parm_tot); |
| 667 |
req->rq_errno = -EIO; |
687 |
goto out_EIO; |
| 668 |
goto out; |
|
|
| 669 |
out_no_mem: |
688 |
out_no_mem: |
| 670 |
printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n", |
689 |
printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n", |
| 671 |
req->rq_trans2bufsize); |
690 |
req->rq_trans2bufsize); |
|
Lines 673-688
Link Here
|
| 673 |
goto out; |
692 |
goto out; |
| 674 |
out_data_grew: |
693 |
out_data_grew: |
| 675 |
printk(KERN_ERR "smb_trans2: data/params grew!\n"); |
694 |
printk(KERN_ERR "smb_trans2: data/params grew!\n"); |
| 676 |
req->rq_errno = -EIO; |
695 |
goto out_EIO; |
| 677 |
goto out; |
|
|
| 678 |
out_bad_parm: |
696 |
out_bad_parm: |
| 679 |
printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n", |
697 |
printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n", |
| 680 |
parm_disp, parm_count, parm_tot); |
698 |
parm_disp, parm_count, parm_tot, parm_offset); |
| 681 |
req->rq_errno = -EIO; |
699 |
goto out_EIO; |
| 682 |
goto out; |
|
|
| 683 |
out_bad_data: |
700 |
out_bad_data: |
| 684 |
printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n", |
701 |
printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n", |
| 685 |
data_disp, data_count, data_tot); |
702 |
data_disp, data_count, data_tot, data_offset); |
|
|
703 |
out_EIO: |
| 686 |
req->rq_errno = -EIO; |
704 |
req->rq_errno = -EIO; |
| 687 |
out: |
705 |
out: |
| 688 |
return req->rq_errno; |
706 |
return req->rq_errno; |