From 689f1eb3719d61700b58f984ac8602837f004f8c Mon Sep 17 00:00:00 2001 From: Gael Blivet Date: Thu, 9 Jul 2026 18:50:46 +0200 Subject: [PATCH] ksmbd: report actual xattr value length in stream enumeration get_file_stream_info() (FileStreamInformation QUERY_INFO) reported each enumerated stream's StreamSize/StreamAllocationSize as stream_name_len -- the byte length of the stream's *name*, not its data. This is the same bug class already fixed for EndOfFile/ AllocationSize on an open stream handle (ksmbd_stream_eof()), just missed at this second site: a client enumerating streams sees a size derived from the name string length instead of the stream's actual content length, inconsistent with what querying the same stream by handle reports. Compute the real value length the same way ksmbd_stream_eof() does, via ksmbd_vfs_casexattr_len() on the already-known xattr key. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Gael Blivet Signed-off-by: Namjae Jeon --- fs/smb/server/smb2pdu.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index e3be1da76dc6..70f8e780da33 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -5952,6 +5952,8 @@ static int get_file_stream_info(struct ksmbd_work *work, struct kstat stat; const struct path *path = &fp->filp->f_path; ssize_t xattr_list_len; + ssize_t slen; + loff_t ssize; int nbytes = 0, streamlen, stream_name_len, next, idx = 0; int buf_free_len; int ret; @@ -6013,8 +6015,20 @@ static int get_file_stream_info(struct ksmbd_work *work, streamlen *= 2; kfree(stream_buf); file_info->StreamNameLength = cpu_to_le32(streamlen); - file_info->StreamSize = cpu_to_le64(stream_name_len); - file_info->StreamAllocationSize = cpu_to_le64(stream_name_len); + /* + * stream_name_len is the byte length of the xattr's *name*, + * not its value -- same class of bug ksmbd_stream_eof() + * (smb2pdu.c) already fixes for EndOfFile/AllocationSize on + * a stream handle; this enumeration path needs the same + * real xattr value length, not the name length reused as a + * size. + */ + slen = ksmbd_vfs_casexattr_len(file_mnt_idmap(fp->filp), + path->dentry, stream_name, + strlen(stream_name) + 1); + ssize = slen < 0 ? 0 : (loff_t)slen; + file_info->StreamSize = cpu_to_le64(ssize); + file_info->StreamAllocationSize = cpu_to_le64(ssize); nbytes += next; buf_free_len -= next;