summaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2ops.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2018-10-25 07:43:36 +0200
committerSteve French <stfrench@microsoft.com>2018-11-02 20:09:41 +0100
commit0c5d6cb6643f48ad3775322f3ebab6c7eb67484e (patch)
tree708f90365fd6d08b197801a8a4d7424b3b87831c /fs/cifs/smb2ops.c
parentMerge tag 'for-linus-20181102' of git://git.kernel.dk/linux-block (diff)
downloadlinux-0c5d6cb6643f48ad3775322f3ebab6c7eb67484e.tar.xz
linux-0c5d6cb6643f48ad3775322f3ebab6c7eb67484e.zip
cifs: fix return value for cifs_listxattr
If the application buffer was too small to fit all the names we would still count the number of bytes and return this for listxattr. This would then trigger a BUG in usercopy.c Fix the computation of the size so that we return -ERANGE correctly when the buffer is too small. This fixes the kernel BUG for xfstest generic/377 Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Diffstat (limited to '')
-rw-r--r--fs/cifs/smb2ops.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 23c0a21a66f8..8489b5f706c3 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -747,6 +747,7 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
int rc = 0;
unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
char *name, *value;
+ size_t buf_size = dst_size;
size_t name_len, value_len, user_name_len;
while (src_size > 0) {
@@ -782,9 +783,10 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
/* 'user.' plus a terminating null */
user_name_len = 5 + 1 + name_len;
- rc += user_name_len;
-
- if (dst_size >= user_name_len) {
+ if (buf_size == 0) {
+ /* skip copy - calc size only */
+ rc += user_name_len;
+ } else if (dst_size >= user_name_len) {
dst_size -= user_name_len;
memcpy(dst, "user.", 5);
dst += 5;
@@ -792,8 +794,7 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
dst += name_len;
*dst = 0;
++dst;
- } else if (dst_size == 0) {
- /* skip copy - calc size only */
+ rc += user_name_len;
} else {
/* stop before overrun buffer */
rc = -ERANGE;