cifs: fix parsing of symbolic link error response
authorRonnie Sahlberg <lsahlber@redhat.com>
Tue, 9 Jul 2019 08:41:11 +0000 (18:41 +1000)
committerSteve French <stfrench@microsoft.com>
Wed, 10 Jul 2019 21:15:45 +0000 (16:15 -0500)
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>
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.h

index 4b0b149..e704e04 100644 (file)
@@ -2605,26 +2605,32 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        err_buf = err_iov.iov_base;
        if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
            err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) {
-               rc = -ENOENT;
+               rc = -EINVAL;
+               goto querty_exit;
+       }
+
+       symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
+       if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
+           le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) {
+               rc = -EINVAL;
                goto querty_exit;
        }
 
        /* open must fail on symlink - reset rc */
        rc = 0;
-       symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
        sub_len = le16_to_cpu(symlink->SubstituteNameLength);
        sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
        print_len = le16_to_cpu(symlink->PrintNameLength);
        print_offset = le16_to_cpu(symlink->PrintNameOffset);
 
        if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
-               rc = -ENOENT;
+               rc = -EINVAL;
                goto querty_exit;
        }
 
        if (err_iov.iov_len <
            SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
-               rc = -ENOENT;
+               rc = -EINVAL;
                goto querty_exit;
        }
 
index 458bad0..7e2e782 100644 (file)
@@ -166,6 +166,8 @@ struct smb2_err_rsp {
        __u8   ErrorData[1];  /* variable length */
 } __packed;
 
+#define SYMLINK_ERROR_TAG 0x4c4d5953
+
 struct smb2_symlink_err_rsp {
        __le32 SymLinkLength;
        __le32 SymLinkErrorTag;