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>
This commit is contained in:
Ronnie Sahlberg 2019-07-09 18:41:11 +10:00 committed by Steve French
parent f5f111c231
commit df070afd9b
2 changed files with 12 additions and 4 deletions

View File

@ -2605,26 +2605,32 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
err_buf = err_iov.iov_base; err_buf = err_iov.iov_base;
if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) { 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; goto querty_exit;
} }
/* open must fail on symlink - reset rc */ /* open must fail on symlink - reset rc */
rc = 0; rc = 0;
symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
sub_len = le16_to_cpu(symlink->SubstituteNameLength); sub_len = le16_to_cpu(symlink->SubstituteNameLength);
sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
print_len = le16_to_cpu(symlink->PrintNameLength); print_len = le16_to_cpu(symlink->PrintNameLength);
print_offset = le16_to_cpu(symlink->PrintNameOffset); print_offset = le16_to_cpu(symlink->PrintNameOffset);
if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
rc = -ENOENT; rc = -EINVAL;
goto querty_exit; goto querty_exit;
} }
if (err_iov.iov_len < if (err_iov.iov_len <
SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
rc = -ENOENT; rc = -EINVAL;
goto querty_exit; goto querty_exit;
} }

View File

@ -166,6 +166,8 @@ struct smb2_err_rsp {
__u8 ErrorData[1]; /* variable length */ __u8 ErrorData[1]; /* variable length */
} __packed; } __packed;
#define SYMLINK_ERROR_TAG 0x4c4d5953
struct smb2_symlink_err_rsp { struct smb2_symlink_err_rsp {
__le32 SymLinkLength; __le32 SymLinkLength;
__le32 SymLinkErrorTag; __le32 SymLinkErrorTag;