|
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 */ |
|
|
| 591 |
data_offset -= hdrlen; |
| 592 |
parm_offset -= hdrlen; |
| 593 |
|
590 |
|
| 594 |
if (parm_count == parm_tot && data_count == data_tot) { |
591 |
if (parm_count == parm_tot && data_count == data_tot) { |
| 595 |
/* |
592 |
/* |
|
Lines 599-615
Link Here
|
| 599 |
* case. It may be a server error to not return a |
597 |
* case. It may be a server error to not return a |
| 600 |
* response that fits. |
598 |
* response that fits. |
| 601 |
*/ |
599 |
*/ |
|
|
600 |
/* _count = 0 is a special case, where data_offset is |
| 601 |
* not used. |
| 602 |
*/ |
| 603 |
if (data_count != 0) { |
| 604 |
if (data_offset < hdrlen) |
| 605 |
goto out_bad_data; |
| 606 |
/* Modify offset for the split header/buffer we use */ |
| 607 |
data_offset -= hdrlen; |
| 608 |
if (data_offset + data_count > req->rq_rlen) |
| 609 |
goto out_bad_data; |
| 610 |
req->rq_ldata = data_count; |
| 611 |
req->rq_data = req->rq_buffer + data_offset; |
| 612 |
} else { |
| 613 |
req->rq_data = NULL; |
| 614 |
req->rq_ldata = 0; |
| 615 |
} |
| 616 |
|
| 617 |
if (parm_count != 0) { |
| 618 |
if (parm_offset < hdrlen) |
| 619 |
goto out_bad_parm; |
| 620 |
/* Modify offset for the split header/buffer we use */ |
| 621 |
parm_offset -= hdrlen; |
| 622 |
if (parm_offset + parm_count > req->rq_rlen) |
| 623 |
goto out_bad_parm; |
| 624 |
req->rq_lparm = parm_count; |
| 625 |
req->rq_parm = req->rq_buffer + parm_offset; |
| 626 |
} else { |
| 627 |
req->rq_lparm = 0; |
| 628 |
req->rq_parm = NULL; |
| 629 |
} |
| 630 |
|
| 602 |
VERBOSE("single trans2 response " |
631 |
VERBOSE("single trans2 response " |
| 603 |
"dcnt=%d, pcnt=%d, doff=%d, poff=%d\n", |
632 |
"dcnt=%d, pcnt=%d, doff=%d, poff=%d\n", |
| 604 |
data_count, parm_count, |
633 |
data_count, parm_count, |
| 605 |
data_offset, parm_offset); |
634 |
data_offset, parm_offset); |
| 606 |
req->rq_ldata = data_count; |
|
|
| 607 |
req->rq_lparm = parm_count; |
| 608 |
req->rq_data = req->rq_buffer + data_offset; |
| 609 |
req->rq_parm = req->rq_buffer + parm_offset; |
| 610 |
return 0; |
635 |
return 0; |
| 611 |
} |
636 |
} |
| 612 |
|
637 |
|
|
|
638 |
if (data_offset < hdrlen) |
| 639 |
goto out_bad_data; |
| 640 |
if (parm_offset < hdrlen) |
| 641 |
goto out_bad_parm; |
| 642 |
parm_offset -= hdrlen; |
| 643 |
data_offset -= hdrlen; |
| 644 |
|
| 645 |
|
| 613 |
VERBOSE("multi trans2 response " |
646 |
VERBOSE("multi trans2 response " |
| 614 |
"frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n", |
647 |
"frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n", |
| 615 |
req->rq_fragment, |
648 |
req->rq_fragment, |
|
Lines 634-639
Link Here
|
| 634 |
req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS); |
665 |
req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS); |
| 635 |
if (!req->rq_trans2buffer) |
666 |
if (!req->rq_trans2buffer) |
| 636 |
goto out_no_mem; |
667 |
goto out_no_mem; |
|
|
668 |
memset(req->rq_trans2buffer, 0, buf_len); |
| 637 |
|
669 |
|
| 638 |
req->rq_parm = req->rq_trans2buffer; |
670 |
req->rq_parm = req->rq_trans2buffer; |
| 639 |
req->rq_data = req->rq_trans2buffer + parm_tot; |
671 |
req->rq_data = req->rq_trans2buffer + parm_tot; |
|
Lines 643-650
Link Here
|
| 643 |
|
675 |
|
| 644 |
if (parm_disp + parm_count > req->rq_total_parm) |
676 |
if (parm_disp + parm_count > req->rq_total_parm) |
| 645 |
goto out_bad_parm; |
677 |
goto out_bad_parm; |
|
|
678 |
if (parm_offset + parm_count > req->rq_rlen) |
| 679 |
goto out_bad_parm; |
| 646 |
if (data_disp + data_count > req->rq_total_data) |
680 |
if (data_disp + data_count > req->rq_total_data) |
| 647 |
goto out_bad_data; |
681 |
goto out_bad_data; |
|
|
682 |
if (data_offset + data_count > req->rq_rlen) |
| 683 |
goto out_bad_data; |
| 648 |
|
684 |
|
| 649 |
inbuf = req->rq_buffer; |
685 |
inbuf = req->rq_buffer; |
| 650 |
memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count); |
686 |
memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count); |
|
Lines 657-664
Link Here
|
| 657 |
* Check whether we've received all of the data. Note that |
693 |
* Check whether we've received all of the data. Note that |
| 658 |
* we use the packet totals -- total lengths might shrink! |
694 |
* we use the packet totals -- total lengths might shrink! |
| 659 |
*/ |
695 |
*/ |
| 660 |
if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) |
696 |
if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) { |
|
|
697 |
req->rq_ldata = data_tot; |
| 698 |
req->rq_lparm = parm_tot; |
| 661 |
return 0; |
699 |
return 0; |
|
|
700 |
} |
| 662 |
return 1; |
701 |
return 1; |
| 663 |
|
702 |
|
| 664 |
out_too_long: |
703 |
out_too_long: |
|
Lines 676-688
Link Here
|
| 676 |
req->rq_errno = -EIO; |
715 |
req->rq_errno = -EIO; |
| 677 |
goto out; |
716 |
goto out; |
| 678 |
out_bad_parm: |
717 |
out_bad_parm: |
| 679 |
printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n", |
718 |
printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d, ofs=%d\n", |
| 680 |
parm_disp, parm_count, parm_tot); |
719 |
parm_disp, parm_count, parm_tot, parm_offset); |
| 681 |
req->rq_errno = -EIO; |
720 |
req->rq_errno = -EIO; |
| 682 |
goto out; |
721 |
goto out; |
| 683 |
out_bad_data: |
722 |
out_bad_data: |
| 684 |
printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n", |
723 |
printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d, ofs=%d\n", |
| 685 |
data_disp, data_count, data_tot); |
724 |
data_disp, data_count, data_tot, data_offset); |
| 686 |
req->rq_errno = -EIO; |
725 |
req->rq_errno = -EIO; |
| 687 |
out: |
726 |
out: |
| 688 |
return req->rq_errno; |
727 |
return req->rq_errno; |