From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (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 7873249620 for ; Thu, 16 Jul 2026 00:12:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784160756; cv=none; b=PY725WLoyJy9Z3hA0Xjqz0DV5/m3FSlZRDUiKsKpJZQDqitk9HE4YgX36mYmTzbRBCL01veKnniz7tV+ZNzOG/fmuWgqa4k28zhKHxaS99BznXNX4CqcVKVQEeGGgONMwl1xxRH03QDlPW61NfLCLC+XpPJzSEaxqAp76JT/ej4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784160756; c=relaxed/simple; bh=blvVtwVMl5QOAh0QlpOTPVCnpqosC8oj89d4AaeSGd0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DbDLkmrAxz+/M0l1so0xSSWzffdbLdhipQyxQ8+uJ+p538xUpmqx3xaHO9QkXEEXXXCb6w5N0BjHoc/WDx8OiXSZXriF5LmHnaTB1SyvNbsjojAhF2TzbZkhJBnClIq6ANvstknWmC3i8WCnvy7AzUGbMXPHun5wLqAnJttH40o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=chenxiaosong.com; spf=pass smtp.mailfrom=chenxiaosong.com; dkim=pass (2048-bit key) header.d=chenxiaosong.com header.i=@chenxiaosong.com header.b=AWfR/vu9; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=chenxiaosong.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chenxiaosong.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=chenxiaosong.com header.i=@chenxiaosong.com header.b="AWfR/vu9" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chenxiaosong.com; s=key1; t=1784160750; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xoi7LZ/SijdXk91aK+aVUF0VjepygkiO+7REmZQ5Od8=; b=AWfR/vu9R4qoEFZqgpoT3VloN2Ezecx30tfLiB2iqD0Fov5FR5uokCqFsswtdZN3uryHlO Xj7T4+x+o1lPq9WeegH2fFav9noF0T96O16ABPDLv5DpUzaWSlfk6SP/xwwCc4vD6l9bz3 eCWY0l9tCWa6F9/mKao+xfhEwgnDmS6jKq6cpbaoiOah/EnwzO/tWebybba/uIshBSync1 Z+QamqaHkK2ujiV+qX6V2+AkV4iv3+69JsvO0Mk3Cxs0gZUzWw9W/q/aA50UuOukPczIVc nwzqzbCBna8PiXfNDpkE14S9pJ3FtJY1fSCclxTQaJ5r7WcK4IuEkoxJsOrJxQ== From: ChenXiaoSong To: smfrench@gmail.com, linkinjeon@kernel.org, pc@manguebit.org, ronniesahlberg@gmail.com, sprasad@microsoft.com, tom@talpey.com, bharathsm@microsoft.com, senozhatsky@chromium.org, dhowells@redhat.com, metze@samba.org, gael.blivet@gmail.com, andriy.shevchenko@linux.intel.com Cc: linux-cifs@vger.kernel.org, ChenXiaoSong Subject: [PATCH v2 1/3] smb/server: fix signing when a response uses more than one iov Date: Thu, 16 Jul 2026 00:11:54 +0000 Message-ID: <20260716001156.671587-2-chenxiaosong@chenxiaosong.com> In-Reply-To: <20260716001156.671587-1-chenxiaosong@chenxiaosong.com> References: <20260716001156.671587-1-chenxiaosong@chenxiaosong.com> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT From: ChenXiaoSong Some SMB responses keep their data in another buffer. The SMB header and the data are then in different iovs. The old code only handled this for SMB2 READ. For other commands, it signed only the last iov. QUERY_INFO and CHANGE_NOTIFY can also use another iov for their data. Their SMB header was not signed, so Windows will client rejected the response. Find the iov that starts with the current SMB header. Sign this iov and all iovs after it. Signed-off-by: ChenXiaoSong --- fs/smb/server/smb2pdu.c | 52 ++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 295cca6cf3ae..966e61788422 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -10624,6 +10624,40 @@ int smb2_check_sign_req(struct ksmbd_work *work) return 1; } +/** + * smb2_get_sign_rsp_iov() - get the iovecs used to sign a response + * @work: work that has the response iovecs + * @hdr: SMB2 header of the response + * @n_vec: set to the number of iovecs to sign + * + * Response data may be in another buffer. In this case, the response uses + * more than one iovec. Find the iovec that starts with @hdr. Sign this + * iovec and all iovecs after it. + * + * Return: The first iovec to sign. + */ +static struct kvec *smb2_get_sign_rsp_iov(struct ksmbd_work *work, + struct smb2_hdr *hdr, int *n_vec) +{ + int i; + + /* + * iov[0] has the RFC1002 message length. It is not part of the SMB2 + * message, so do not sign it. + */ + for (i = 1; i <= work->iov_idx; i++) { + if (work->iov[i].iov_base == hdr) { + *n_vec = work->iov_idx - i + 1; + return &work->iov[i]; + } + } + + WARN_ON_ONCE(work->iov_idx < 1 || + work->iov[work->iov_idx].iov_base != hdr); + *n_vec = 1; + return &work->iov[work->iov_idx]; +} + /** * smb2_set_sign_rsp() - handler for rsp packet sign processing * @work: smb work containing notify command buffer @@ -10634,18 +10668,13 @@ void smb2_set_sign_rsp(struct ksmbd_work *work) struct smb2_hdr *hdr; char signature[SMB2_HMACSHA256_SIZE]; struct kvec *iov; - int n_vec = 1; + int n_vec; hdr = ksmbd_resp_buf_curr(work); hdr->Flags |= SMB2_FLAGS_SIGNED; memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE); - if (hdr->Command == SMB2_READ) { - iov = &work->iov[work->iov_idx - 1]; - n_vec++; - } else { - iov = &work->iov[work->iov_idx]; - } + iov = smb2_get_sign_rsp_iov(work, hdr, &n_vec); ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec, signature); @@ -10728,7 +10757,7 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) char signature[SMB2_CMACAES_SIZE]; struct kvec *iov; u16 command = conn->ops->get_cmd_val(work); - int n_vec = 1; + int n_vec; char *signing_key; hdr = ksmbd_resp_buf_curr(work); @@ -10750,12 +10779,7 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) hdr->Flags |= SMB2_FLAGS_SIGNED; memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE); - if (hdr->Command == SMB2_READ) { - iov = &work->iov[work->iov_idx - 1]; - n_vec++; - } else { - iov = &work->iov[work->iov_idx]; - } + iov = smb2_get_sign_rsp_iov(work, hdr, &n_vec); ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature); memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE); -- 2.54.0