From: Yibo Liu <yiboliume@gmail.com>
To: "Philipp Reisner" <philipp.reisner@linbit.com>,
"Lars Ellenberg" <lars.ellenberg@linbit.com>,
"Christoph Böhmwalder" <christoph.boehmwalder@linbit.com>,
"Jens Axboe" <axboe@kernel.dk>
Cc: drbd-dev@lists.linux.dev, linux-block@vger.kernel.org,
linux-kernel@vger.kernel.org, Yibo Liu <yiboliume@gmail.com>
Subject: [PATCH 2/2] drbd: validate digest size in checksum resync and verify requests
Date: Thu, 15 Oct 2026 15:28:00 -0700 [thread overview]
Message-ID: <20261015222800.85928-3-yiboliume@gmail.com> (raw)
In-Reply-To: <20261015222800.85928-1-yiboliume@gmail.com>
receive_DataRequest() takes the digest length of P_CSUM_RS_REQUEST and
P_OV_REPLY packets from the packet header and passes it to kmalloc()
without any check. The worker later compares the received digest with
one computed by the local csums or verify algorithm. A size mismatch is
only reported by D_ASSERT(), and memcmp() runs anyway.
A digest that is shorter than the algorithm's digest size therefore
makes w_e_end_csum_rs_req() and w_e_end_ov_reply() read past the end of
the digest_info allocation:
BUG: KASAN: slab-out-of-bounds in memcmp+0x1b8/0x1d8
Read of size 8 at addr ffff00000a638610 by task drbd_w_r1/212
Call trace:
memcmp
w_e_end_csum_rs_req
drbd_worker
Allocated by task 240:
__kmalloc_noprof
receive_DataRequest
drbd_receiver
A digest length larger than the page allocator can serve triggers the
WARN_ON_ONCE() for oversized allocations, as GFP_NOIO does not include
__GFP_NOWARN:
WARNING: mm/page_alloc.c:5340 at __alloc_frozen_pages_noprof
Call trace:
___kmalloc_large_node
__kmalloc_noprof
receive_DataRequest
drbd_receiver
Reject these packets unless the digest length matches the digest size
of the configured csums or verify algorithm, and also reject them when
no such algorithm is configured. In the worker, only compare digests of
the same size: the peer can switch csums-alg or verify-alg with
P_SYNC_PARAM after the request was received, and a size mismatch is
then treated as "not in sync" instead of reading out of bounds.
Fixes: b411b3637fa7 ("The DRBD driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Yibo Liu <yiboliume@gmail.com>
---
Notes:
- Reproduced in the same setup with csums-alg=sha1, the proxy rewriting
one P_CSUM_RS_REQUEST: a 0-byte digest gives the KASAN report above,
a 1 GiB digest length gives the WARNING above. With the patch both are
rejected with "CsumRSRequest: unexpected digest size ..." and there is
no KASAN report or warning. A complete csums-alg resync followed by an
online verify with verify-alg=sha1, without tampering, still passes.
The harness is available on request.
- In LINBIT's DRBD 9 tree, receive_digest() only rejects negative sizes
and the sender keeps the D_ASSERT() before memcmp(), so the pending
DRBD 9 rework series probably needs the same checks. I have not
checked the posted series itself.
drivers/block/drbd/drbd_receiver.c | 9 +++++++++
drivers/block/drbd/drbd_worker.c | 8 ++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 97b306676626..87e714477050 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2629,6 +2629,7 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
sector_t capacity;
struct drbd_peer_request *peer_req;
struct digest_info *di = NULL;
+ struct crypto_shash *tfm;
int size, verb;
struct p_block_req *p = pi->data;
@@ -2713,6 +2714,14 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
case P_OV_REPLY:
case P_CSUM_RS_REQUEST:
+ tfm = pi->cmd == P_OV_REPLY ? connection->verify_tfm :
+ connection->csums_tfm;
+ if (!tfm || pi->size != crypto_shash_digestsize(tfm)) {
+ drbd_err(device, "%s: unexpected digest size %u\n",
+ cmdname(pi->cmd), pi->size);
+ goto out_free_e;
+ }
+
di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO);
if (!di)
goto out_free_e;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 0697f99fed18..31e54960c5de 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -1174,8 +1174,8 @@ int w_e_end_csum_rs_req(struct drbd_work *w, int cancel)
* introducing more locking mechanisms */
if (peer_device->connection->csums_tfm) {
digest_size = crypto_shash_digestsize(peer_device->connection->csums_tfm);
- D_ASSERT(device, digest_size == di->digest_size);
- digest = kmalloc(digest_size, GFP_NOIO);
+ if (digest_size == di->digest_size)
+ digest = kmalloc(digest_size, GFP_NOIO);
}
if (digest) {
drbd_csum_ee(peer_device->connection->csums_tfm, peer_req, digest);
@@ -1301,8 +1301,8 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel)
if (digest) {
drbd_csum_ee(peer_device->connection->verify_tfm, peer_req, digest);
- D_ASSERT(device, digest_size == di->digest_size);
- eq = !memcmp(digest, di->digest, digest_size);
+ eq = digest_size == di->digest_size &&
+ !memcmp(digest, di->digest, digest_size);
kfree(digest);
}
}
--
2.39.5 (Apple Git-154)
prev parent reply other threads:[~2026-10-15 22:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 22:27 [PATCH 0/2] drbd: validate payload sizes received from the peer Yibo Liu
2026-10-15 22:27 ` [PATCH 1/2] drbd: reject data replies whose size does not match the request Yibo Liu
2026-10-15 22:28 ` Yibo Liu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261015222800.85928-3-yiboliume@gmail.com \
--to=yiboliume@gmail.com \
--cc=axboe@kernel.dk \
--cc=christoph.boehmwalder@linbit.com \
--cc=drbd-dev@lists.linux.dev \
--cc=lars.ellenberg@linbit.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=philipp.reisner@linbit.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox