From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794061703; b=jIeOcU8XwinCVcuXd++v2aoHQ7DwnAubhoMAxqhbQQ6bgI9Q3exzgBDv2Q75vjpIa2Vn 3mnkUcJETZlz6y9dBekI9qj+CZy5nS1kQfWLLGePoe8nUUc4J/vqq68bR3FDfmQsnZlwD Unaa7ZdfpDjU7geSL7pvMCuTldoPj9nFG/SpfweWw7NY6vOMuBvGDCIxxHkzwmYEC7zBv l1Aj/ALaECUB19C4J2nkQn+Yo6PpvUH3nbDgoJTaCzqMMkbWO0Rj3Ryg2NlPsctk6HXg6 4ywvHavWD07bsP2bWgcPUxo6LLZ/6JPQacC9OcdvKv5fEC7blWPG+rzPIqahg/azc0Q== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794061703; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=0A1MdA4epFdSpX828yfDMFr/bFV8azuKwbdHVBzNl/M=; b=HP+v8EX9uJLxOmgggZ+t8HDzJNBOHIulglkzCbVjFAzgGNLhp6mEmJCCFjc2fv9zqbB5 H6xBAdiFAmJB/LZ7yMA4w5WtuNoO7UInKysklHP+tTOksrwus+G4OigxdhfeRv6yS+frp YsfHwNt3zXZlifyh6XCVdr3g5GVDrOPLccrKsvkncApLf6va4Yg2psNP81wjNj+pMslNu /3KZgkpLI7qtALprY/48t0Cwx7JfCHEx9uf6LmkgELB0JLv3GyeF1Cq1O+WbhmzyJe6tk OxSnjsVw6s6qpOxK1mCmomGjqnO0dVWLLq0fypSg47GRfJ3BW1+LWRN/y/8Y43CaYbw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=W34QriQk; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C754B606A326; Sat, 7 Nov 2026 14:28:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=W34QriQk Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6D7FF1F008A1; Sat, 7 Nov 2026 14:28:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794061702; bh=0A1MdA4epFdSpX828yfDMFr/bFV8azuKwbdHVBzNl/M=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=W34QriQk1TQHVGrsAEfgZB054Q8duczUya/ngO6bvHw1nE/6Hf7raEfnxP6c3gOP6 OegyF9TL8eIVZEHWbejzAXYOzCdq0QcOrIOUsv9VDhb52CGCSLrAslV2oiF9IAr4PX rqACoe4iJWCTZQWGbWnUvHArYoiJE4D6Wm6C20pU= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Ratnaker Gautam , Namjae Jeon , Paulo Alcantara Subject: [PATCH 6.12 0752/1536] smb: client: validate NT transaction response layout and offsets Date: Sat, 7 Nov 2026 08:46:08 -0500 Message-ID: <20261107135018.652425279@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134957.653319350@linuxfoundation.org> References: <20261107134957.653319350@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ratnaker Gautam commit 83d0d5e0ca22233c75daf139ec0063b9d2ff1ac7 upstream. validate_ntransact() assumes that the response uses the fixed 18-word NT transaction layout. A different WordCount makes get_bcc() locate the byte count at a different offset from pSMBr->ByteCount, allowing the subsequent bounds checks to use inconsistent response boundaries. The function also turns the 32-bit ParameterOffset and DataOffset fields into pointers before checking their bounds. On a 32-bit client, a large offset can wrap the pointer below end_of_smb and pass the one-sided pointer comparison. The caller then dereferences the parameter pointer or copies from the data pointer. Require the expected WordCount before reading the byte count. Check each offset and count against the received SMB length as integers before forming either pointer. Use subtraction after validating the offset so that the range checks cannot overflow. Reported-by: Ratnaker Gautam Fixes: 0a4b92c05ed0 ("[CIFS] Add worker function for Get ACL cifs style") Cc: stable@vger.kernel.org Signed-off-by: Ratnaker Gautam Reviewed-by: Namjae Jeon Signed-off-by: Paulo Alcantara Signed-off-by: Greg Kroah-Hartman --- fs/smb/client/cifssmb.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -3401,9 +3401,10 @@ static int validate_ntransact(char *buf, char **ppparm, char **ppdata, __u32 *pparmlen, __u32 *pdatalen) { - char *end_of_smb; __u32 data_count, data_offset, parm_count, parm_offset; struct smb_com_ntransact_rsp *pSMBr; + size_t buflen; + char *end_buf; u16 bcc; *pdatalen = 0; @@ -3414,37 +3415,42 @@ validate_ntransact(char *buf, char **ppp pSMBr = (struct smb_com_ntransact_rsp *)buf; + if (pSMBr->hdr.WordCount != 18) { + cifs_dbg(FYI, "invalid NT transaction WordCount %u\n", + pSMBr->hdr.WordCount); + return -EINVAL; + } + bcc = get_bcc(&pSMBr->hdr); - end_of_smb = 2 /* sizeof byte count */ + bcc + - (char *)&pSMBr->ByteCount; + end_buf = 2 /* sizeof byte count */ + bcc + (char *)&pSMBr->ByteCount; + buflen = end_buf - buf; data_offset = le32_to_cpu(pSMBr->DataOffset); data_count = le32_to_cpu(pSMBr->DataCount); parm_offset = le32_to_cpu(pSMBr->ParameterOffset); parm_count = le32_to_cpu(pSMBr->ParameterCount); - *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; - *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; - /* should we also check that parm and data areas do not overlap? */ - if (*ppparm > end_of_smb) { + if (parm_offset > buflen) { cifs_dbg(FYI, "parms start after end of smb\n"); return -EINVAL; - } else if (parm_count + *ppparm > end_of_smb) { + } else if (parm_count > buflen - parm_offset) { cifs_dbg(FYI, "parm end after end of smb\n"); return -EINVAL; - } else if (*ppdata > end_of_smb) { + } else if (data_offset > buflen) { cifs_dbg(FYI, "data starts after end of smb\n"); return -EINVAL; - } else if (data_count + *ppdata > end_of_smb) { - cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n", - *ppdata, data_count, (data_count + *ppdata), - end_of_smb, pSMBr); + } else if (data_count > buflen - data_offset) { + cifs_dbg(FYI, "data offset %u + count %u past smb length %zu\n", + data_offset, data_count, buflen); return -EINVAL; } else if (parm_count + data_count > bcc) { cifs_dbg(FYI, "parm count and data count larger than SMB\n"); return -EINVAL; } + + *ppparm = buf + parm_offset; + *ppdata = buf + data_offset; *pdatalen = data_count; *pparmlen = parm_count; return 0;