diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2014-02-14 04:31:02 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2014-02-14 17:50:47 -0500 |
commit | 2365c4eaf077c48574ab6f143960048fc0f31518 (patch) | |
tree | d710354608b5fe6a559dc5c0045ab0e6104ffe28 /fs/cifs | |
parent | 5d81de8e8667da7135d3a32a964087c0faf5483f (diff) |
CIFS: Fix too big maxBuf size for SMB3 mounts
SMB3 servers can respond with MaxTransactSize of more than 4M
that can cause a memory allocation error returned from kmalloc
in a lock codepath. Also the client doesn't support multicredit
requests now and allows buffer sizes of 65536 bytes only. Set
MaxTransactSize to this maximum supported value.
Cc: stable@vger.kernel.org # 3.7+
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/smb2glob.h | 3 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 14 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 4 |
3 files changed, 10 insertions, 11 deletions
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h index c38350851b08..bc0bb9c34f72 100644 --- a/fs/cifs/smb2glob.h +++ b/fs/cifs/smb2glob.h | |||
@@ -57,4 +57,7 @@ | |||
57 | #define SMB2_CMACAES_SIZE (16) | 57 | #define SMB2_CMACAES_SIZE (16) |
58 | #define SMB3_SIGNKEY_SIZE (16) | 58 | #define SMB3_SIGNKEY_SIZE (16) |
59 | 59 | ||
60 | /* Maximum buffer size value we can send with 1 credit */ | ||
61 | #define SMB2_MAX_BUFFER_SIZE 65536 | ||
62 | |||
60 | #endif /* _SMB2_GLOB_H */ | 63 | #endif /* _SMB2_GLOB_H */ |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 757da3e54d3d..192f51a12cf1 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -182,11 +182,8 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) | |||
182 | /* start with specified wsize, or default */ | 182 | /* start with specified wsize, or default */ |
183 | wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; | 183 | wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; |
184 | wsize = min_t(unsigned int, wsize, server->max_write); | 184 | wsize = min_t(unsigned int, wsize, server->max_write); |
185 | /* | 185 | /* set it to the maximum buffer size value we can send with 1 credit */ |
186 | * limit write size to 2 ** 16, because we don't support multicredit | 186 | wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); |
187 | * requests now. | ||
188 | */ | ||
189 | wsize = min_t(unsigned int, wsize, 2 << 15); | ||
190 | 187 | ||
191 | return wsize; | 188 | return wsize; |
192 | } | 189 | } |
@@ -200,11 +197,8 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) | |||
200 | /* start with specified rsize, or default */ | 197 | /* start with specified rsize, or default */ |
201 | rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; | 198 | rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; |
202 | rsize = min_t(unsigned int, rsize, server->max_read); | 199 | rsize = min_t(unsigned int, rsize, server->max_read); |
203 | /* | 200 | /* set it to the maximum buffer size value we can send with 1 credit */ |
204 | * limit write size to 2 ** 16, because we don't support multicredit | 201 | rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE); |
205 | * requests now. | ||
206 | */ | ||
207 | rsize = min_t(unsigned int, rsize, 2 << 15); | ||
208 | 202 | ||
209 | return rsize; | 203 | return rsize; |
210 | } | 204 | } |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a3f7a9c3cc69..860344701067 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -413,7 +413,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
413 | 413 | ||
414 | /* SMB2 only has an extended negflavor */ | 414 | /* SMB2 only has an extended negflavor */ |
415 | server->negflavor = CIFS_NEGFLAVOR_EXTENDED; | 415 | server->negflavor = CIFS_NEGFLAVOR_EXTENDED; |
416 | server->maxBuf = le32_to_cpu(rsp->MaxTransactSize); | 416 | /* set it to the maximum buffer size value we can send with 1 credit */ |
417 | server->maxBuf = min_t(unsigned int, le32_to_cpu(rsp->MaxTransactSize), | ||
418 | SMB2_MAX_BUFFER_SIZE); | ||
417 | server->max_read = le32_to_cpu(rsp->MaxReadSize); | 419 | server->max_read = le32_to_cpu(rsp->MaxReadSize); |
418 | server->max_write = le32_to_cpu(rsp->MaxWriteSize); | 420 | server->max_write = le32_to_cpu(rsp->MaxWriteSize); |
419 | /* BB Do we need to validate the SecurityMode? */ | 421 | /* BB Do we need to validate the SecurityMode? */ |