From ba9572bc43d04d71ba52ae7f20645f1eafe86875 Mon Sep 17 00:00:00 2001 From: Alon Shakevsky Date: Sat, 29 Aug 2026 06:27:46 +0000 Subject: [PATCH] ksmbd: validate normalized name response length FILE_NORMALIZED_NAME_INFORMATION converts the open file path to UTF-16. smb2_allocate_rsp_buf() leaves these responses in the 448-byte small buffer, and get_file_normalized_name_info() converts the path without checking the remaining space. An authenticated client can query a long path and make smbConvertToUTF16() write beyond work->response_buf. Use the large response buffer for normalized-name queries. Before conversion, verify that the response has room for the worst-case UTF-16 output and its terminator. Fixes: 10aeff72ab82 ("ksmbd: support normalized name information") Assisted-by: Antiproof:GPT-5.6-Sol Signed-off-by: Alon Shakevsky Signed-off-by: Namjae Jeon --- fs/smb/server/smb2pdu.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 8c589110460a..d656832d82ef 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -878,7 +878,8 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) req = smb_get_msg(work->request_buf); if ((req->InfoType == SMB2_O_INFO_FILE && (req->FileInfoClass == FILE_FULL_EA_INFORMATION || - req->FileInfoClass == FILE_ALL_INFORMATION)) || + req->FileInfoClass == FILE_ALL_INFORMATION || + req->FileInfoClass == FILE_NORMALIZED_NAME_INFORMATION)) || req->InfoType == SMB2_O_INFO_SECURITY) sz = large_sz; } @@ -6789,7 +6790,7 @@ static int get_file_normalized_name_info(struct ksmbd_work *work, { struct smb2_file_alt_name_info *file_info; char *filename, *normalized, *stream_name; - int conv_len, filename_len; + int buf_free_len, conv_len, filename_len; if (work->conn->dialect < SMB311_PROT_ID) { rsp->hdr.Status = STATUS_NOT_SUPPORTED; @@ -6813,6 +6814,14 @@ static int get_file_normalized_name_info(struct ksmbd_work *work, return -ENOMEM; filename_len = strlen(normalized); + buf_free_len = smb2_resp_buf_len(work, sizeof(*rsp) + + sizeof(*file_info)); + if (buf_free_len < 0 || + (size_t)buf_free_len < (filename_len + 1) * sizeof(__le16)) { + kfree(normalized); + return -EINVAL; + } + file_info = (struct smb2_file_alt_name_info *)rsp->Buffer; conv_len = smbConvertToUTF16((__le16 *)file_info->FileName, normalized, filename_len,