[PATCH 1/1] cachefiles: avoid slab out-of-bounds read when tracing short aux data
Ren Wei <[email protected]> Sun, 28 Jun 2026 19:28:16 +0800
| Newsgroups | dev.linux.lists.netfs |
|---|---|
| Message-ID | <82edfddccd38dc1ba67bc614f24e8248bab447a1.1782637741.git.xizh2024@lzu.edu.cn> |
From: Zihan Xi <[email protected]> trace_cachefiles_coherency() logs disk-side auxiliary data passed from cachefiles_set_object_xattr() and cachefiles_check_auxdata(). Both call sites always used be64_to_cpup(buf->data), reading eight bytes even when the xattr tail only contains cookie->aux_len bytes. 9p registers FS-Cache cookies with a four-byte qid.version aux payload. When the cachefiles coherency tracepoint is enabled, the extra read past the kmalloc() allocation triggers KASAN slab-out-of-bounds reports in fscache_cookie_worker. Read at most aux_len bytes into a u64 before passing the value to the tracepoint. Fixes: 229105e5cfd9 ("cachefiles: Add auxiliary data trace") Cc: [email protected] Reported-by: Yuan Tan <[email protected]> Reported-by: Xin Liu <[email protected]> Cc: David Howells <[email protected]> Cc: [email protected] Assisted-by: Codex:gpt-5.4 Signed-off-by: Zihan Xi <[email protected]> Signed-off-by: Ren Wei <[email protected]> --- fs/cachefiles/xattr.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index f8ae78b3f7b6..a11ea858c046 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -28,6 +28,18 @@ struct cachefiles_xattr { static const char cachefiles_xattr_cache[] = XATTR_USER_PREFIX "CacheFiles.cache"; +static u64 cachefiles_disk_aux_for_trace(const void *data, unsigned int len) +{ + u64 aux = 0; + + if (len == 0) + return 0; + if (len >= sizeof(u64)) + return be64_to_cpup(data); + memcpy(&aux, data, len); + return aux; +} + struct cachefiles_vol_xattr { __be32 reserved; /* Reserved, should be 0 */ __u8 data[]; /* netfs volume coherency data */ @@ -77,7 +89,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_disk_aux_for_trace(buf->data, len), buf->content, cachefiles_coherency_set_fail); if (ret != -ENOMEM) @@ -86,7 +98,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_disk_aux_for_trace(buf->data, len), buf->content, cachefiles_coherency_set_ok); } @@ -148,7 +160,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_disk_aux_for_trace(buf->data, len), buf->content, why); kfree(buf); return ret; -- 2.43.0