aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2019-07-09 04:41:11 -0400
committerSteve French <stfrench@microsoft.com>2019-07-10 17:15:45 -0400
commitdf070afd9b8c952eacf49db54cae7138eb9deaeb (patch)
tree537e6118629e984ee62764f450abe0bf66738f3b /fs/cifs
parentf5f111c231f56e56e186c9a61a9d22fb8bf05faa (diff)
cifs: fix parsing of symbolic link error response
RHBZ: 1672539 In smb2_query_symlink(), if we are parsing the error buffer but it is not something we recognize as a symlink we should return -EINVAL and not -ENOENT. I.e. the entry does exist, it is just not something we recognize. Additionally, add check to verify that that the errortag and the reparsetag all make sense. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Acked-by: Paulo Alcantara <palcantara@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/smb2ops.c14
-rw-r--r--fs/cifs/smb2pdu.h2
2 files changed, 12 insertions, 4 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 4b0b14946343..e704e04891fb 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -2605,26 +2605,32 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
2605 err_buf = err_iov.iov_base; 2605 err_buf = err_iov.iov_base;
2606 if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || 2606 if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
2607 err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) { 2607 err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) {
2608 rc = -ENOENT; 2608 rc = -EINVAL;
2609 goto querty_exit;
2610 }
2611
2612 symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
2613 if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
2614 le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) {
2615 rc = -EINVAL;
2609 goto querty_exit; 2616 goto querty_exit;
2610 } 2617 }
2611 2618
2612 /* open must fail on symlink - reset rc */ 2619 /* open must fail on symlink - reset rc */
2613 rc = 0; 2620 rc = 0;
2614 symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
2615 sub_len = le16_to_cpu(symlink->SubstituteNameLength); 2621 sub_len = le16_to_cpu(symlink->SubstituteNameLength);
2616 sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); 2622 sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
2617 print_len = le16_to_cpu(symlink->PrintNameLength); 2623 print_len = le16_to_cpu(symlink->PrintNameLength);
2618 print_offset = le16_to_cpu(symlink->PrintNameOffset); 2624 print_offset = le16_to_cpu(symlink->PrintNameOffset);
2619 2625
2620 if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { 2626 if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
2621 rc = -ENOENT; 2627 rc = -EINVAL;
2622 goto querty_exit; 2628 goto querty_exit;
2623 } 2629 }
2624 2630
2625 if (err_iov.iov_len < 2631 if (err_iov.iov_len <
2626 SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { 2632 SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
2627 rc = -ENOENT; 2633 rc = -EINVAL;
2628 goto querty_exit; 2634 goto querty_exit;
2629 } 2635 }
2630 2636
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 458bad01ca74..7e2e782f8edd 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -166,6 +166,8 @@ struct smb2_err_rsp {
166 __u8 ErrorData[1]; /* variable length */ 166 __u8 ErrorData[1]; /* variable length */
167} __packed; 167} __packed;
168 168
169#define SYMLINK_ERROR_TAG 0x4c4d5953
170
169struct smb2_symlink_err_rsp { 171struct smb2_symlink_err_rsp {
170 __le32 SymLinkLength; 172 __le32 SymLinkLength;
171 __le32 SymLinkErrorTag; 173 __le32 SymLinkErrorTag;