Commit 85db6b7a authored by Ronnie Sahlberg's avatar Ronnie Sahlberg Committed by Steve French

cifs: make sure we do not overflow the max EA buffer size

RHBZ: 1752437

Before we add a new EA we should check that this will not overflow
the maximum buffer we have available to read the EAs back.
Otherwise we can get into a situation where the EAs are so big that
we can not read them back to the client and thus we can not list EAs
anymore or delete them.
Signed-off-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
CC: Stable <stable@vger.kernel.org>
parent 2c6251ad
...@@ -1116,7 +1116,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1116,7 +1116,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
void *data[1]; void *data[1];
struct smb2_file_full_ea_info *ea = NULL; struct smb2_file_full_ea_info *ea = NULL;
struct kvec close_iov[1]; struct kvec close_iov[1];
int rc; struct smb2_query_info_rsp *rsp;
int rc, used_len = 0;
if (smb3_encryption_required(tcon)) if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ; flags |= CIFS_TRANSFORM_REQ;
...@@ -1139,6 +1140,38 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1139,6 +1140,38 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
cifs_sb); cifs_sb);
if (rc == -ENODATA) if (rc == -ENODATA)
goto sea_exit; goto sea_exit;
} else {
/* If we are adding a attribute we should first check
* if there will be enough space available to store
* the new EA. If not we should not add it since we
* would not be able to even read the EAs back.
*/
rc = smb2_query_info_compound(xid, tcon, utf16_path,
FILE_READ_EA,
FILE_FULL_EA_INFORMATION,
SMB2_O_INFO_FILE,
CIFSMaxBufSize -
MAX_SMB2_CREATE_RESPONSE_SIZE -
MAX_SMB2_CLOSE_RESPONSE_SIZE,
&rsp_iov[1], &resp_buftype[1], cifs_sb);
if (rc == 0) {
rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
used_len = le32_to_cpu(rsp->OutputBufferLength);
}
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
resp_buftype[1] = CIFS_NO_BUFFER;
memset(&rsp_iov[1], 0, sizeof(rsp_iov[1]));
rc = 0;
/* Use a fudge factor of 256 bytes in case we collide
* with a different set_EAs command.
*/
if(CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 <
used_len + ea_name_len + ea_value_len + 1) {
rc = -ENOSPC;
goto sea_exit;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment