aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2ops.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-10-28 08:39:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-28 08:39:35 -0700
commit781402340475144bb360e32bb7437fa4b84cadc3 (patch)
tree38c845e2de383b64ce05024581fe78db0788be0c /fs/cifs/smb2ops.c
parentMerge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs (diff)
parentSMB3: Validate negotiate request must always be signed (diff)
downloadlinux-dev-781402340475144bb360e32bb7437fa4b84cadc3.tar.xz
linux-dev-781402340475144bb360e32bb7437fa4b84cadc3.zip
Merge tag '4.14-smb3-fixes-for-stable' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "Various SMB3 fixes for 4.14 and stable" * tag '4.14-smb3-fixes-for-stable' of git://git.samba.org/sfrench/cifs-2.6: SMB3: Validate negotiate request must always be signed SMB: fix validate negotiate info uninitialised memory use SMB: fix leak of validate negotiate info response buffer CIFS: Fix NULL pointer deref on SMB2_tcon() failure CIFS: do not send invalid input buffer on QUERY_INFO requests cifs: Select all required crypto modules CIFS: SMBD: Fix the definition for SMB2_CHANNEL_RDMA_V1_INVALIDATE cifs: handle large EA requests more gracefully in smb2+ Fix encryption labels and lengths for SMB3.1.1
Diffstat (limited to 'fs/cifs/smb2ops.c')
-rw-r--r--fs/cifs/smb2ops.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 0dafdbae1f8c..bdb963d0ba32 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -522,6 +522,7 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_open_parms oparms;
struct cifs_fid fid;
struct smb2_file_full_ea_info *smb2_data;
+ int ea_buf_size = SMB2_MIN_EA_BUF;
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
if (!utf16_path)
@@ -541,14 +542,32 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
return rc;
}
- smb2_data = kzalloc(SMB2_MAX_EA_BUF, GFP_KERNEL);
- if (smb2_data == NULL) {
- SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
- return -ENOMEM;
+ while (1) {
+ smb2_data = kzalloc(ea_buf_size, GFP_KERNEL);
+ if (smb2_data == NULL) {
+ SMB2_close(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid);
+ return -ENOMEM;
+ }
+
+ rc = SMB2_query_eas(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid,
+ ea_buf_size, smb2_data);
+
+ if (rc != -E2BIG)
+ break;
+
+ kfree(smb2_data);
+ ea_buf_size <<= 1;
+
+ if (ea_buf_size > SMB2_MAX_EA_BUF) {
+ cifs_dbg(VFS, "EA size is too large\n");
+ SMB2_close(xid, tcon, fid.persistent_fid,
+ fid.volatile_fid);
+ return -ENOMEM;
+ }
}
- rc = SMB2_query_eas(xid, tcon, fid.persistent_fid, fid.volatile_fid,
- smb2_data);
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
if (!rc)