summary refs log tree commit diff
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2018-10-25 15:43:36 +1000
committerSteve French <stfrench@microsoft.com>2018-11-02 14:09:41 -0500
commit0c5d6cb6643f48ad3775322f3ebab6c7eb67484e (patch)
tree708f90365fd6d08b197801a8a4d7424b3b87831c
parent5f21585384a4a69b8bfdd2cae7e3648ae805f57d (diff)
downloadlinux-0c5d6cb6643f48ad3775322f3ebab6c7eb67484e.tar.gz
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>
-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;