From nobody Mon Sep 28 13:59:30 2026 Received: from mta0.migadu.com (out-172.mta0.migadu.com [91.218.175.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D144B48A2D1 for ; Thu, 20 Aug 2026 21:45:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787262358; cv=none; b=fwzN5PyDujt800RfAdNmtCeITQRgy/JiX4/0FX+q+3xVKyAjplxx3UwDnykns1iNmQZxTbkPdrnsyJj0vF6calpBMasi0QxoHp9sczaf6d6nUiCEgVY1YDzcKnVHgN2m+c/zl+2rsTNG7/g/aIh02u1dJ1teL6qPzA8tKse1280= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787262358; c=relaxed/simple; bh=rqBwdTzJTsUHLdH9mNFjmD0wlARq772TB++7ROC8Uhg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iW0It9cpp2+LerU0PjBJabmiOQe54OolenpW+mgrxfdyQj1eyYgUlbekh6Ldg7t6cipJNjvIZUr9F/RegwEqM+SBx6bilK2h+NyAocQ7PJG8ivcEsrRoT3U7qTSdN3JAYFjPaPf/66EV+Wn8qrUYVxaCFvTvddxeOY/G4HzktkU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cressey.dev; spf=pass smtp.mailfrom=cressey.dev; dkim=pass (2048-bit key) header.d=cressey.dev header.i=@cressey.dev header.b=H4Unc+aO; arc=none smtp.client-ip=91.218.175.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cressey.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cressey.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cressey.dev header.i=@cressey.dev header.b="H4Unc+aO" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=rqBwdTzJTsUHLdH9mNFjmD0wlARq772TB++7ROC8Uhg=; c=simple/simple; d=cressey.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787262353; v=1; x=1787867153; b=H4Unc+aO+kHgzlH8sEN9C+sbhuux7XoEfmpoEgE73j3K35g+vvU7NkszluVmwFSFwBFwJDuL be6pC227lRFLZCrb6/Hngr23yTE2cXYWq13Hv190PzhM7CcZ5VY1d68/67kJzBqeNrHtJlUYLlt B4Ug3qHrs0lfV5YQdDGX2S4+DRefzxSmUrDGfufbXbjn73pmmCe39LeA6ziBiciZKGiJJ6Ub/aZ 3e3stB/sGHNC8hB+lJOC3af80wc22OmiwNYr+n/eYzYrbFYO+n21DgJcGn8qxuULZqTlcV8i2iC wJPvWsPeUUvo91mzhWrH/R3OWdInc9LX6nWbK6H81vWKw== X-Envelope-To: linux-kernel@vger.kernel.org Received: from coder-bcressey-whiskers-0.coder-bcressey-whiskers.remote-dev.svc.cluster.local (35.83.186.167) by smtp.migadu.com with ESMTPS id b6f451db4fd30599; Thu, 20 Aug 2026 21:45:53 +0000 X-Mizu-Trace-ID: b6f451db4fd30599 X-Migadu-Flow: FLOW_OUT From: Ben Cressey Date: Thu, 20 Aug 2026 21:44:57 +0000 Subject: [PATCH 1/2] dm-integrity: fix buffer overflow with keyed discard Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260820-dm-integrity-discard-v1-1-196d3618d09a@cressey.dev> References: <20260820-dm-integrity-discard-v1-0-196d3618d09a@cressey.dev> In-Reply-To: <20260820-dm-integrity-discard-v1-0-196d3618d09a@cressey.dev> To: Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Benjamin Marzinski , Shukai Ni , Jo Van Bulck Cc: dm-devel@lists.linux.dev, linux-kernel@vger.kernel.org, Mike Snitzer , "Jose Fernandez (Anthropic)" , Ben Cressey X-Mailer: b4 0.15.2 Since commit 68c5c42567bc ("dm-integrity: replace forgeable discard filler with a keyed sector marker"), integrity_metadata computes a checksum for every discarded block into the "checksums" buffer. integrity_sector_checksum always writes the whole digest. So if the tag size is smaller than the digest size, the checksum of the last block that fits into the buffer is written past the end of it. For example, with hmac(sha256) and tag size 16, a 4MiB discard writes 16 bytes past the kmalloc'ed page. Fix this by subtracting extra_space from the buffer size when computing max_blocks, like we do for writes. Fixes: 68c5c42567bc ("dm-integrity: replace forgeable discard filler with a= keyed sector marker") Reviewed-by: Jose Fernandez (Anthropic) Signed-off-by: Ben Cressey Assisted-by: Claude:unspecified --- Found with KASAN on current mainline (after the 7.3 dm merge): brd, "0 integrity /dev/ram0 0 16 J 2 internal_hash:hmac(sha256): allow_discards_keyed", 8MiB written, then BLKDISCARD of 4MiB: BUG: KASAN: slab-out-of-bounds in __hmac_sha256_final+0x1be/0x1e0 Write of size 4 at addr ff11000104b05000 by task kworker/0:0/9 Workqueue: dm-integrity-offload integrity_bio_wait integrity_sector_checksum_shash+0x181/0x490 integrity_metadata+0x101e/0x18a0 dm_integrity_map_continue+0x1eb2/0x34d0 The buggy address is located 0 bytes to the right of allocated 4096-byte region --- drivers/md/dm-integrity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index c50feaa98bf9e..73c1db7e55d5c 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -1980,7 +1980,7 @@ static void integrity_metadata(struct work_struct *w) if (unlikely(dio->op =3D=3D REQ_OP_DISCARD)) { unsigned int bi_size =3D dio->bio_details.bi_iter.bi_size; unsigned int max_size =3D likely(checksums !=3D checksums_onstack) ? PA= GE_SIZE : HASH_MAX_DIGESTSIZE; - unsigned int max_blocks =3D max_size / ic->tag_size; + unsigned int max_blocks =3D (max_size - extra_space) / ic->tag_size; sector_t sector =3D dio->range.logical_sector; =20 if (!ic->discard_keyed) --=20 2.53.0 From nobody Mon Sep 28 13:59:30 2026 Received: from mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EBB2463B74 for ; Thu, 20 Aug 2026 21:46:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787262373; cv=none; b=qghZGtc6QtVyo5+FSo6BNsPRPYEW5PWtq9m0ICJQ4D/aMS1M5qmubHROQ/OVJa2frls9OtQp516VUEnMTi3DaddVkQxZ70KnI/Z1vnawmbEkv7tHWeZGGUTLquikSZDZTxgRhnWs8xPqgRgc0RdSeM7fCG10d88puoo0GyWE/KA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787262373; c=relaxed/simple; bh=RSZ1ThSZgOWxnWB2KV4RYcYDFdabNu3Qx7dkm8ktJss=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M7FwMG3IeZOdpcHSX03lJ/7xKTsvKrVgEE8XbdM7sjAtD3AwZ/WiiywdjaPVLh5bMcRiw4JoUFMSpMFP2cug1fW8svNPiJx4pDIvcXMcs7WA6zIfDZ+k4CmXXLFBxoNp6QXRiGxXsTnhjFh9eJXrJNFD+vvmm3FREavj/KEx+SI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cressey.dev; spf=pass smtp.mailfrom=cressey.dev; dkim=pass (2048-bit key) header.d=cressey.dev header.i=@cressey.dev header.b=PMtGePUe; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cressey.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cressey.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cressey.dev header.i=@cressey.dev header.b="PMtGePUe" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=RSZ1ThSZgOWxnWB2KV4RYcYDFdabNu3Qx7dkm8ktJss=; c=simple/simple; d=cressey.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787262370; v=1; x=1787867170; b=PMtGePUewx6wVb5nyBSrEtBaDV53K5MIxZgUAGRi2A4J80J5sP3ptJd5B98c5NAK+j1BSj1r 8ycLYoh1LtfS70f5mCghuyQAUqSO0mMFVcBdILIYVFzOXcIz3oPZe63wh4AaL5pmWJzt0FnaKRn ibJii2V1MdbKHFlzLmSDaA6cz58HowdHqxmQUEZiMaaZjxITfmyxwLnn+o/XRKzIr6OyDoxsQAh SO0sE54nvH9q/wbphEvRhfM4gWOLHsG91cTCPx5bdlhvBotIgMvKGPgg+eVIMCSCPblnNduEJ4r i47jEgaKdWjTTJFMuh7/zNo7bV3T/Vuc/pk8Agix00Gog== X-Envelope-To: linux-kernel@vger.kernel.org Received: from coder-bcressey-whiskers-0.coder-bcressey-whiskers.remote-dev.svc.cluster.local (35.83.186.167) by smtp.migadu.com with ESMTPS id a1f09cbef526edeb; Thu, 20 Aug 2026 21:46:00 +0000 X-Mizu-Trace-ID: a1f09cbef526edeb X-Migadu-Flow: FLOW_OUT From: Ben Cressey Date: Thu, 20 Aug 2026 21:44:58 +0000 Subject: [PATCH 2/2] dm-integrity: fix infinite loop on discard with large tag size Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260820-dm-integrity-discard-v1-2-196d3618d09a@cressey.dev> References: <20260820-dm-integrity-discard-v1-0-196d3618d09a@cressey.dev> In-Reply-To: <20260820-dm-integrity-discard-v1-0-196d3618d09a@cressey.dev> To: Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Benjamin Marzinski , Shukai Ni , Jo Van Bulck Cc: dm-devel@lists.linux.dev, linux-kernel@vger.kernel.org, Mike Snitzer , stable@vger.kernel.org, "Jose Fernandez (Anthropic)" , Ben Cressey X-Mailer: b4 0.15.2 When integrity_metadata handles a discard, it fills a buffer with DISCARD_FILLER and writes it over the tags, max_blocks blocks at a time. If the kmalloc fails, the buffer is the on-stack array checksums_onstack and max_size is set to HASH_MAX_DIGESTSIZE. So if the tag size is larger than HASH_MAX_DIGESTSIZE, max_blocks is zero, bi_size is never decremented and the loop never terminates. Fix this by using sizeof(checksums_onstack) as max_size. The array has MAX_TAG_SIZE bytes since commit b93b6643e9b5 ("dm integrity: fix a crash with unusually large tag size"), so max_blocks is at least 1. Fixes: 84597a44a9d8 ("dm integrity: add optional discard support") Cc: stable@vger.kernel.org Reviewed-by: Jose Fernandez (Anthropic) Signed-off-by: Ben Cressey Assisted-by: Claude:unspecified Reviewed-by: Jo Van Bulck Reviewed-by: Shukai Ni --- The natural trigger needs the kmalloc to fail, so this was tested with the fallback forced (a test-only hunk that frees the buffer for discards): J mode, internal_hash:sha256, tag_size 100, allow_discards, BLKDISCARD of 16 MiB. Without the fix the discard never completes and a dm-integrity-offload kworker spins in integrity_metadata -> dm_integrity_rw_tag (soft lockup with preempt=3Dnone); with the fix it completes immediately. This goes after 1/2; on its own it would let the keyed-discard fallback overflow checksums_onstack for tag sizes below the digest size. For stable: 1/2 is not stable material and it changes the context line right above this hunk, so this patch will not apply verbatim to released trees. The backport is the same one-line change; I will send it in reply to the failed-to-apply notice. --- drivers/md/dm-integrity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 73c1db7e55d5c..48eca96ca6d8c 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -1979,7 +1979,7 @@ static void integrity_metadata(struct work_struct *w) =20 if (unlikely(dio->op =3D=3D REQ_OP_DISCARD)) { unsigned int bi_size =3D dio->bio_details.bi_iter.bi_size; - unsigned int max_size =3D likely(checksums !=3D checksums_onstack) ? PA= GE_SIZE : HASH_MAX_DIGESTSIZE; + unsigned int max_size =3D likely(checksums !=3D checksums_onstack) ? PA= GE_SIZE : sizeof(checksums_onstack); unsigned int max_blocks =3D (max_size - extra_space) / ic->tag_size; sector_t sector =3D dio->range.logical_sector; =20 --=20 2.53.0