aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c80
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
2569int 2568int
2570CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2569CIFSSMBQueryReparseLinkInfo(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
2667qreparse_out: 2662qreparse_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