[PATCH] cachefiles: Fix OOB access in coherency trace

Chandradhar Kumar <[email protected]>
Newsgroups dev.linux.lists.netfs,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The coherency trace read the first 8 bytes of the auxiliary data with
be64_to_cpup(). However the auxiliary data stored in a cachefiles
xattr is variable length.

9P uses the 4-byte QID version as auxiliary data. Thus buf->data
contains only those 4 bytes, but the coherency trace unconditionally
reads 8 bytes from it, causing KASAN slab-out-of-bounds report.

Copy up to the first 8 bytes of the auxiliary data into an 8-byte
buffer before reading it as a big-endian value.

Fixes: 229105e5cfd9 ("cachefiles: Add auxiliary data trace")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=62b392c7348147ad767d
Signed-off-by: Chandradhar Kumar <[email protected]>
---
 fs/cachefiles/xattr.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index f8ae78b3f7b6..e4cd635e8abe 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -25,6 +25,14 @@ struct cachefiles_xattr {
 	__u8	data[];		/* netfs coherency data */
 } __packed;
 
+static u64 cachefiles_get_aux_u64(const void *data, unsigned int len)
+{
+	__be64 aux = 0;
+
+	memcpy(&aux, data, min_t(unsigned int, len, sizeof(aux)));
+	return be64_to_cpup(&aux);
+}
+
 static const char cachefiles_xattr_cache[] =
 	XATTR_USER_PREFIX "CacheFiles.cache";
 
@@ -77,7 +85,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
 		trace_cachefiles_vfs_error(object, file_inode(file), ret,
 					   cachefiles_trace_setxattr_error);
 		trace_cachefiles_coherency(object, file_inode(file)->i_ino,
-					   be64_to_cpup((__be64 *)buf->data),
+					   cachefiles_get_aux_u64(buf->data, len),
 					   buf->content,
 					   cachefiles_coherency_set_fail);
 		if (ret != -ENOMEM)
@@ -86,7 +94,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
 				"Failed to set xattr with error %d", ret);
 	} else {
 		trace_cachefiles_coherency(object, file_inode(file)->i_ino,
-					   be64_to_cpup((__be64 *)buf->data),
+					   cachefiles_get_aux_u64(buf->data, len),
 					   buf->content,
 					   cachefiles_coherency_set_ok);
 	}
@@ -148,7 +156,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file
 
 out:
 	trace_cachefiles_coherency(object, file_inode(file)->i_ino,
-				   be64_to_cpup((__be64 *)buf->data),
+				   cachefiles_get_aux_u64(buf->data, len),
 				   buf->content, why);
 	kfree(buf);
 	return ret;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.