From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5960C3AB291; Wed, 23 Sep 2026 14:19:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790173174; cv=none; b=ivk4Q9aG+HtHgazbitQzE1RPb+TN1V2KmWahOmYZVCNqKOBq2bprKjRJtL2kykir0cRdI7H5/XXqlhPXcM8tPPLdFqfC/Jz2RPOHK1uUIwrJ3lvH3FSEwx/M2fVcYJvkGORC7cI11Dje3AZE9QmvwXefpfSci519UF+4V1mHP84= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790173174; c=relaxed/simple; bh=Tqi//yeXlAxmg2C4FjUcM/s0RMGSOJFd+DzcDbqjmNw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BefOO8Ulw74NMl1nlXEhGo1RpBHCkuzZT+HWmMeMQwibUGlKqzzmD7bV2kqa/rlBvSMIKL6N/9p0zuFKNPtERqFXZ178TwKVJh38qL2mnDa9Jl/rw5ctc2W7N1uxZA7bWb6iffe8OB+jUAcM0IAk2FcHU7x3R0sQbhbBv/zye0I= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=iJmby97E; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="iJmby97E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B1F871F000FF; Wed, 23 Sep 2026 14:19:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1790173173; bh=8eIp9OLJYP8kZRWQTYz0dLDMib+HYaunF7h8UihWGfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=iJmby97Ecmr6dV4cjAOMBWvzK6L995NT+r2Qazpk3usaJIi+uofpcuI+fcFT20j0K 1qHwFqc8MNzGZBsZsHT4TGdR+VKpnvf5E7DCeHZ6pPy01r7RAFp7jQyppI2Ql9/k1e ge7P+1lAFk+1ukDQLcP7eTRELb6fK9LB/6+oWEdk= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Namjae Jeon , Sasha Levin Subject: [PATCH 7.2 164/438] ksmbd: return buffer overflow for partial filesystem info Date: Wed, 23 Sep 2026 16:03:05 +0200 Message-ID: <20260923140649.023740362@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260923140644.756254324@linuxfoundation.org> References: <20260923140644.756254324@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.2-stable review patch. If anyone has any objections, please let me know. ------------------ From: Namjae Jeon [ Upstream commit 0ecd35fac4b4f2828490689b46039744d201dcb0 ] The query-info buffer check returns STATUS_INFO_LENGTH_MISMATCH for every output buffer smaller than the complete response. Variable-length filesystem information instead requires STATUS_BUFFER_OVERFLOW when the fixed portion fits but the complete data does not. Pass the fixed size for each filesystem information class to the buffer checker. Keep INFO_LENGTH_MISMATCH for buffers below that size, and return BUFFER_OVERFLOW with a response truncated to the requested length for larger partial buffers. This fixes smb2.getinfo.qfs_buffercheck. Signed-off-by: Namjae Jeon Stable-dep-of: 9fa26285ae70 ("ksmbd: keep compound responses on query info errors") Signed-off-by: Sasha Levin --- fs/smb/server/smb2pdu.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 3cb39dc7b149c..cd533dbdc2b23 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -5622,21 +5622,30 @@ int smb2_query_dir(struct ksmbd_work *work) /** * buffer_check_err() - helper function to check buffer errors * @reqOutputBufferLength: max buffer length expected in command response + * @fixed_len: minimum fixed response length * @rsp: query info response buffer contains output buffer length * @rsp_org: base response buffer pointer in case of chained response * * Return: 0 on success, otherwise error */ static int buffer_check_err(int reqOutputBufferLength, + unsigned int fixed_len, struct smb2_query_info_rsp *rsp, void *rsp_org) { - if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) { + unsigned int output_len = le32_to_cpu(rsp->OutputBufferLength); + + if (reqOutputBufferLength < fixed_len) { pr_err("Invalid Buffer Size Requested\n"); rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr)); return -EINVAL; } + + if (reqOutputBufferLength < output_len) { + rsp->hdr.Status = STATUS_BUFFER_OVERFLOW; + rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength); + } return 0; } @@ -5699,11 +5708,13 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess, case FILE_STANDARD_INFORMATION: get_standard_info_pipe(rsp, rsp_org); rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + le32_to_cpu(rsp->OutputBufferLength), rsp, rsp_org); break; case FILE_INTERNAL_INFORMATION: get_internal_info_pipe(rsp, id, rsp_org); rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + le32_to_cpu(rsp->OutputBufferLength), rsp, rsp_org); break; default: @@ -6524,6 +6535,7 @@ static int smb2_get_info_file(struct ksmbd_work *work, } if (!rc) rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + le32_to_cpu(rsp->OutputBufferLength), rsp, work->response_buf); ksmbd_fd_put(work, fp); @@ -6545,6 +6557,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, struct kstatfs stfs; struct path path; int rc = 0, len; + unsigned int fixed_len = 0; if (!share->path) return -EIO; @@ -6579,6 +6592,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->DeviceCharacteristics |= cpu_to_le32(FILE_READ_ONLY_DEVICE); rsp->OutputBufferLength = cpu_to_le32(8); + fixed_len = 8; break; } case FS_ATTRIBUTE_INFORMATION: @@ -6631,6 +6645,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->FileSystemNameLen = cpu_to_le32(len); sz = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO) + len; rsp->OutputBufferLength = cpu_to_le32(sz); + fixed_len = 16; break; } case FS_VOLUME_INFORMATION: @@ -6658,6 +6673,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->SupportsObjects = 0; sz = sizeof(struct filesystem_vol_info) + len; rsp->OutputBufferLength = cpu_to_le32(sz); + fixed_len = 24; break; } case FS_SIZE_INFORMATION: @@ -6670,6 +6686,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->SectorsPerAllocationUnit = cpu_to_le32(1); info->BytesPerSector = cpu_to_le32(stfs.f_bsize); rsp->OutputBufferLength = cpu_to_le32(24); + fixed_len = 24; break; } case FS_FULL_SIZE_INFORMATION: @@ -6685,6 +6702,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->SectorsPerAllocationUnit = cpu_to_le32(1); info->BytesPerSector = cpu_to_le32(stfs.f_bsize); rsp->OutputBufferLength = cpu_to_le32(32); + fixed_len = 32; break; } case FS_OBJECT_ID_INFORMATION: @@ -6705,6 +6723,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->extended_info.rel_date = 0; memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0")); rsp->OutputBufferLength = cpu_to_le32(64); + fixed_len = 64; break; } case FS_SECTOR_SIZE_INFORMATION: @@ -6726,6 +6745,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->ByteOffsetForSectorAlignment = 0; info->ByteOffsetForPartitionAlignment = 0; rsp->OutputBufferLength = cpu_to_le32(28); + fixed_len = 28; break; } case FS_CONTROL_INFORMATION: @@ -6746,6 +6766,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID); info->Padding = 0; rsp->OutputBufferLength = cpu_to_le32(48); + fixed_len = 48; break; } case FS_POSIX_INFORMATION: @@ -6766,6 +6787,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, info->TotalFileNodes = cpu_to_le64(stfs.f_files); info->FreeFileNodes = cpu_to_le64(stfs.f_ffree); rsp->OutputBufferLength = cpu_to_le32(56); + fixed_len = 56; } break; } @@ -6774,6 +6796,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, return -EOPNOTSUPP; } rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + fixed_len, rsp, work->response_buf); path_put(&path); @@ -6875,6 +6898,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work, rsp->OutputBufferLength = cpu_to_le32(secdesclen); rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + le32_to_cpu(rsp->OutputBufferLength), rsp, work->response_buf); if (rc) goto err_out; -- 2.53.0