diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index b968e5bd7df3..0ac32bd336d7 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -2564,7 +2564,6 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, | |||
2564 | *pparmlen = parm_count; | 2564 | *pparmlen = parm_count; |
2565 | return 0; | 2565 | return 0; |
2566 | } | 2566 | } |
2567 | #endif /* CIFS_EXPERIMENTAL */ | ||
2568 | 2567 | ||
2569 | int | 2568 | int |
2570 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | 2569 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, |
@@ -2611,59 +2610,55 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | |||
2611 | } else { /* decode response */ | 2610 | } else { /* decode response */ |
2612 | __u32 data_offset = le32_to_cpu(pSMBr->DataOffset); | 2611 | __u32 data_offset = le32_to_cpu(pSMBr->DataOffset); |
2613 | __u32 data_count = le32_to_cpu(pSMBr->DataCount); | 2612 | __u32 data_count = le32_to_cpu(pSMBr->DataCount); |
2614 | if ((pSMBr->ByteCount < 2) || (data_offset > 512)) | 2613 | if ((pSMBr->ByteCount < 2) || (data_offset > 512)) { |
2615 | /* BB also check enough total bytes returned */ | 2614 | /* BB also check enough total bytes returned */ |
2616 | rc = -EIO; /* bad smb */ | 2615 | rc = -EIO; /* bad smb */ |
2617 | else { | 2616 | goto qreparse_out; |
2618 | if (data_count && (data_count < 2048)) { | 2617 | } |
2619 | char *end_of_smb = 2 /* sizeof byte count */ + | 2618 | if (data_count && (data_count < 2048)) { |
2620 | pSMBr->ByteCount + | 2619 | char *end_of_smb = 2 /* sizeof byte count */ + |
2621 | (char *)&pSMBr->ByteCount; | 2620 | pSMBr->ByteCount + (char *)&pSMBr->ByteCount; |
2622 | 2621 | ||
2623 | struct reparse_data *reparse_buf = | 2622 | struct reparse_data *reparse_buf = |
2624 | (struct reparse_data *) | 2623 | (struct reparse_data *) |
2625 | ((char *)&pSMBr->hdr.Protocol | 2624 | ((char *)&pSMBr->hdr.Protocol |
2626 | + data_offset); | 2625 | + data_offset); |
2627 | if ((char *)reparse_buf >= end_of_smb) { | 2626 | if ((char *)reparse_buf >= end_of_smb) { |
2628 | rc = -EIO; | 2627 | rc = -EIO; |
2629 | goto qreparse_out; | 2628 | goto qreparse_out; |
2630 | } | 2629 | } |
2631 | if ((reparse_buf->LinkNamesBuf + | 2630 | if ((reparse_buf->LinkNamesBuf + |
2632 | reparse_buf->TargetNameOffset + | 2631 | reparse_buf->TargetNameOffset + |
2633 | reparse_buf->TargetNameLen) > | 2632 | reparse_buf->TargetNameLen) > end_of_smb) { |
2634 | end_of_smb) { | 2633 | cFYI(1, ("reparse buf beyond SMB")); |
2635 | cFYI(1, ("reparse buf beyond SMB")); | 2634 | rc = -EIO; |
2636 | rc = -EIO; | 2635 | goto qreparse_out; |
2637 | goto qreparse_out; | 2636 | } |
2638 | } | ||
2639 | 2637 | ||
2640 | if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { | 2638 | if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { |
2641 | name_len = UniStrnlen((wchar_t *) | 2639 | cifs_from_ucs2(symlinkinfo, (__le16 *) |
2642 | (reparse_buf->LinkNamesBuf + | 2640 | (reparse_buf->LinkNamesBuf + |
2643 | reparse_buf->TargetNameOffset), | 2641 | reparse_buf->TargetNameOffset), |
2644 | min(buflen/2, | 2642 | buflen, |
2645 | reparse_buf->TargetNameLen / 2)); | 2643 | reparse_buf->TargetNameLen, |
2646 | cifs_strfromUCS_le(symlinkinfo, | 2644 | nls_codepage, 0); |
2647 | (__le16 *) (reparse_buf->LinkNamesBuf + | 2645 | } else { /* ASCII names */ |
2648 | reparse_buf->TargetNameOffset), | 2646 | strncpy(symlinkinfo, |
2649 | name_len, nls_codepage); | 2647 | reparse_buf->LinkNamesBuf + |
2650 | } else { /* ASCII names */ | 2648 | reparse_buf->TargetNameOffset, |
2651 | strncpy(symlinkinfo, | 2649 | min_t(const int, buflen, |
2652 | reparse_buf->LinkNamesBuf + | 2650 | reparse_buf->TargetNameLen)); |
2653 | reparse_buf->TargetNameOffset, | ||
2654 | min_t(const int, buflen, | ||
2655 | reparse_buf->TargetNameLen)); | ||
2656 | } | ||
2657 | } else { | ||
2658 | rc = -EIO; | ||
2659 | cFYI(1, ("Invalid return data count on " | ||
2660 | "get reparse info ioctl")); | ||
2661 | } | 2651 | } |
2662 | symlinkinfo[buflen] = 0; /* just in case so the caller | 2652 | } else { |
2663 | does not go off the end of the buffer */ | 2653 | rc = -EIO; |
2664 | cFYI(1, ("readlink result - %s", symlinkinfo)); | 2654 | cFYI(1, ("Invalid return data count on " |
2655 | "get reparse info ioctl")); | ||
2665 | } | 2656 | } |
2657 | symlinkinfo[buflen] = 0; /* just in case so the caller | ||
2658 | does not go off the end of the buffer */ | ||
2659 | cFYI(1, ("readlink result - %s", symlinkinfo)); | ||
2666 | } | 2660 | } |
2661 | |||
2667 | qreparse_out: | 2662 | qreparse_out: |
2668 | cifs_buf_release(pSMB); | 2663 | cifs_buf_release(pSMB); |
2669 | 2664 | ||
@@ -2672,6 +2667,7 @@ qreparse_out: | |||
2672 | 2667 | ||
2673 | return rc; | 2668 | return rc; |
2674 | } | 2669 | } |
2670 | #endif /* CIFS_EXPERIMENTAL */ | ||
2675 | 2671 | ||
2676 | #ifdef CONFIG_CIFS_POSIX | 2672 | #ifdef CONFIG_CIFS_POSIX |
2677 | 2673 | ||