From nobody Fri Oct 24 20:20:08 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8A65C00140 for ; Mon, 15 Aug 2022 23:35:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353514AbiHOXfF (ORCPT ); Mon, 15 Aug 2022 19:35:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353413AbiHOX2L (ORCPT ); Mon, 15 Aug 2022 19:28:11 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C66AE14E12B; Mon, 15 Aug 2022 13:07:35 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id CBA15B81158; Mon, 15 Aug 2022 20:07:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1D359C433B5; Mon, 15 Aug 2022 20:07:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660594052; bh=RxDjTeYo2nNQwW/9yi+9WMD7splED4n7H/+zLWc2KMo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QGB5Vn5DjwfOEN/QaAPcP5QcUDf4F0kncXszJkg1gkvIOZToITgqXCjHDG3FSqhml vOJbt2JEb4RWEOt5wHJ+KqZcIZrVkH/S7dcDECESMz7OyOnmOlYvLmTZNbxfeO7e1V 1EralQvYF1zSH4sXpUzkhoroof7UUcEW1GI6gX14= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marios Makassikis , Namjae Jeon , Steve French , Sasha Levin Subject: [PATCH 5.18 1048/1095] ksmbd: validate length in smb2_write() Date: Mon, 15 Aug 2022 20:07:27 +0200 Message-Id: <20220815180512.428425284@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180429.240518113@linuxfoundation.org> References: <20220815180429.240518113@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Marios Makassikis [ Upstream commit 158a66b245739e15858de42c0ba60fcf3de9b8e6 ] The SMB2 Write packet contains data that is to be written to a file or to a pipe. Depending on the client, there may be padding between the header and the data field. Currently, the length is validated only in the case padding is present. Since the DataOffset field always points to the beginning of the data, there is no need to have a special case for padding. By removing this, the length is validated in both cases. Signed-off-by: Marios Makassikis Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/ksmbd/smb2pdu.c | 49 +++++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 30 deletions(-) --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -6344,23 +6344,18 @@ static noinline int smb2_write_pipe(stru length =3D le32_to_cpu(req->Length); id =3D req->VolatileFileId; =20 - if (le16_to_cpu(req->DataOffset) =3D=3D - offsetof(struct smb2_write_req, Buffer)) { - data_buf =3D (char *)&req->Buffer[0]; - } else { - if ((u64)le16_to_cpu(req->DataOffset) + length > - get_rfc1002_len(work->request_buf)) { - pr_err("invalid write data offset %u, smb_len %u\n", - le16_to_cpu(req->DataOffset), - get_rfc1002_len(work->request_buf)); - err =3D -EINVAL; - goto out; - } - - data_buf =3D (char *)(((char *)&req->hdr.ProtocolId) + - le16_to_cpu(req->DataOffset)); + if ((u64)le16_to_cpu(req->DataOffset) + length > + get_rfc1002_len(work->request_buf)) { + pr_err("invalid write data offset %u, smb_len %u\n", + le16_to_cpu(req->DataOffset), + get_rfc1002_len(work->request_buf)); + err =3D -EINVAL; + goto out; } =20 + data_buf =3D (char *)(((char *)&req->hdr.ProtocolId) + + le16_to_cpu(req->DataOffset)); + rpc_resp =3D ksmbd_rpc_write(work->sess, id, data_buf, length); if (rpc_resp) { if (rpc_resp->flags =3D=3D KSMBD_RPC_ENOTIMPLEMENTED) { @@ -6505,22 +6500,16 @@ int smb2_write(struct ksmbd_work *work) =20 if (req->Channel !=3D SMB2_CHANNEL_RDMA_V1 && req->Channel !=3D SMB2_CHANNEL_RDMA_V1_INVALIDATE) { - if (le16_to_cpu(req->DataOffset) =3D=3D - offsetof(struct smb2_write_req, Buffer)) { - data_buf =3D (char *)&req->Buffer[0]; - } else { - if ((u64)le16_to_cpu(req->DataOffset) + length > - get_rfc1002_len(work->request_buf)) { - pr_err("invalid write data offset %u, smb_len %u\n", - le16_to_cpu(req->DataOffset), - get_rfc1002_len(work->request_buf)); - err =3D -EINVAL; - goto out; - } - - data_buf =3D (char *)(((char *)&req->hdr.ProtocolId) + - le16_to_cpu(req->DataOffset)); + if ((u64)le16_to_cpu(req->DataOffset) + length > + get_rfc1002_len(work->request_buf)) { + pr_err("invalid write data offset %u, smb_len %u\n", + le16_to_cpu(req->DataOffset), + get_rfc1002_len(work->request_buf)); + err =3D -EINVAL; + goto out; } + data_buf =3D (char *)(((char *)&req->hdr.ProtocolId) + + le16_to_cpu(req->DataOffset)); =20 ksmbd_debug(SMB, "flags %u\n", le32_to_cpu(req->Flags)); if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)