Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH 0/4] RDMA/rxe: Fix u64 iova-overflow family in MR/ODP/RESP/MW paths
@ 2026-05-21 19:44 Tymbark7372
  2026-05-21 19:44 ` [PATCH 1/4] RDMA/rxe: Fix u64 iova+length overflow in mr_check_range Tymbark7372
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Tymbark7372 @ 2026-05-21 19:44 UTC (permalink / raw)
  To: linux-rdma; +Cc: zyjzyj2000, jgg, leonro, stable, Tymbark7372

This patchset fixes a family of u64 overflow bugs in the rxe Soft-RoCE
driver.  All four sites share one root cause: addition of an
attacker-influenced iova/addr (u64) with an attacker-influenced
length/resid (size_t/u32/int promoted to u64), without overflow
check, leading to an OOB read/write primitive in the rxe responder
workqueue.

I originally reported these to security@kernel.org.  Jason Gunthorpe
confirmed that rxe and siw are development-only drivers without
embargo handling and asked me to send patches publicly, so I'm
posting here per his direction.  security@kernel.org is intentionally
not in Cc per Jason's instruction.

This is a resend of the patches I sent earlier today as attachments.
Zhu Yanjun pointed out attachments aren't the convention and asked
for inline format via git send-email.

Patches:

  1/4: rxe_mr.c mr_check_range
       The USER/MEM_REG case computes iova + length and compares to
       mr->ibmr.iova + mr->ibmr.length.  Both additions wrap in u64.
       Use check_add_overflow() for both ends.

  2/4: rxe_odp.c rxe_check_pagefault
       Loop condition addr < iova + length wraps when iova is near
       U64_MAX and length is positive.  Compute iova_end with
       check_add_overflow() once and use it in the loop condition.

  3/4: rxe_resp.c duplicate_request
       Third clause iova + resid > res->read.va_org + res->read.length
       has u64 wrap on both sides.  Use check_add_overflow() for both
       ends.  (Site A in check_rkey, also in rxe_resp.c, calls into
       mr_check_range and is closed by patch 1.)

  4/4: rxe_mw.c rxe_check_bind_mw
       Same wrap class as patch 1.  Found by sibling-site grep; not on
       the OOB-write path of the three primary bugs but a
       structurally-identical u64 wrap that would let an attacker bind
       a memory window outside its parent MR's range.

Verification:

Each of the three primary sibling triggers (patches 1, 2, 3) has been
exercised on v7.1.0-rc3 + KASAN in QEMU as the OOB-write case.
Patches 1 and 3 produce a single-page-fault Oops in rxe_mr_copy after
the wrap.  Patch 2 produces a single-page-fault Oops in
rxe_odp_mr_copy.  All three are triggered by a single ibv_post_send
from an unprivileged local user with /dev/infiniband/uverbs0 open.
A working LPE exploit demonstrated end-to-end privilege escalation
via the rxe_odp path under the verification config (KASAN dev-build,
selinux=0, nokaslr).  Full PoC and writeup were attached to the
original security@kernel.org submission.

After applying all four patches, the same triggers no longer fire;
the wrap checks correctly reject the attacker iova.  Re-tested in the
same QEMU+KASAN configuration.

The trigger PoCs are simple libibverbs programs (one per sibling)
that I am happy to provide on request.

Fixes / stable:

  1/4: Fixes 8700e3e7c485 ("Soft RoCE driver"), v4.8+
  2/4: Fixes 2fae67ab63db ("RDMA/rxe: Add support for Send/Recv/Write/Read with ODP"), v6.15+
  3/4: Fixes 8700e3e7c485 ("Soft RoCE driver"), v4.8+
  4/4: Fixes 8700e3e7c485 ("Soft RoCE driver"), v4.8+

Pre-f04d5b3d916c LTS branches carry the older wrap form
  iova > mr->ibmr.iova + mr->ibmr.length - length
instead of the current `iova + length > ...` shape.  Patches 1, 3, 4
will need a backport variant for those branches; I can provide on
request.

Tymbark7372 (4):
  RDMA/rxe: Fix u64 iova+length overflow in mr_check_range
  RDMA/rxe: Fix u64 iova+length overflow in rxe_check_pagefault
  RDMA/rxe: Fix u64 iova+resid overflow in duplicate_request
  RDMA/rxe: Fix u64 addr+length overflow in rxe_check_bind_mw

 drivers/infiniband/sw/rxe/rxe_mr.c   | 12 +++++++++---
 drivers/infiniband/sw/rxe/rxe_odp.c  | 10 ++++++++--
 drivers/infiniband/sw/rxe/rxe_resp.c | 11 ++++++++---
 drivers/infiniband/sw/rxe/rxe_mw.c   | 11 ++++++++---
 4 files changed, 33 insertions(+), 11 deletions(-)

--
2.43.0


^ permalink raw reply	[flat|nested] 11+ messages in thread
* [PATCH 0/4] RDMA/rxe: Fix u64 iova-overflow family in MR/ODP/RESP/MW paths
@ 2026-05-21 15:39 Tymbark7372
  2026-05-21 15:46 ` Zhu Yanjun
  0 siblings, 1 reply; 11+ messages in thread
From: Tymbark7372 @ 2026-05-21 15:39 UTC (permalink / raw)
  To: linux-rdma@vger.kernel.org
  Cc: zyjzyj2000@gmail.com, jgg@nvidia.com, leonro@nvidia.com,
	stable@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 3792 bytes --]

This series fixes a family of u64 overflow bugs in the rxe Soft-RoCE
driver.  All four sites share one root cause: addition of an
attacker-influenced iova/addr (u64) with an attacker-influenced
length/resid (size_t/u32/int promoted to u64), without overflow
check, leading to an OOB read/write primitive in the rxe responder
workqueue.

I originally reported these to security@kernel.org.  Jason Gunthorpe
confirmed that rxe and siw are development-only drivers without
embargo handling and asked me to send patches publicly, so this
series follows that direction.  security@kernel.org is intentionally
not in Cc per Jason's instruction.

Patches:

  1/4: rxe_mr.c mr_check_range
       The USER/MEM_REG case computes iova + length and compares to
       mr->ibmr.iova + mr->ibmr.length.  Both additions wrap in u64.
       Use check_add_overflow() for both ends.

  2/4: rxe_odp.c rxe_check_pagefault
       Loop condition addr < iova + length wraps when iova is near
       U64_MAX and length is positive.  Compute iova_end with
       check_add_overflow() once and use it in the loop condition.

  3/4: rxe_resp.c duplicate_request
       Third clause iova + resid > res->read.va_org + res->read.length
       has u64 wrap on both sides.  Use check_add_overflow() for both
       ends.  (Site A in check_rkey, also in rxe_resp.c, calls into
       mr_check_range and is closed by patch 1.)

  4/4: rxe_mw.c rxe_check_bind_mw
       Same wrap class as patch 1.  Found by sibling-site grep; not on
       the OOB-write path of the three primary bugs but a
       structurally-identical u64 wrap that would let an attacker bind
       a memory window outside its parent MR's range.

Verification:

Each of the three primary sibling triggers (patches 1, 2, 3) has been
exercised on v7.1.0-rc3 + KASAN in QEMU as the OOB-write case.
Patches 1 and 3 produce a single-page-fault Oops in rxe_mr_copy after
the wrap.  Patch 2 produces a single-page-fault Oops in
rxe_odp_mr_copy.  All three are triggered by a single ibv_post_send
from an unprivileged local user with /dev/infiniband/uverbs0 open.
A working LPE exploit demonstrated end-to-end privilege escalation
via the rxe_odp path under the verification config (KASAN dev-build,
selinux=0, nokaslr).  Full PoC and writeup were attached to the
original security@kernel.org submission.

After applying all four patches, the same triggers no longer fire;
the wrap checks correctly reject the attacker iova.  Re-tested in the
same QEMU+KASAN configuration.

The trigger PoCs are simple libibverbs programs (one per sibling)
that I am happy to provide on request.

Fixes / stable:

  1/4: Fixes 8700e3e7c485 ("Soft RoCE driver"), v4.8+
  2/4: Fixes 2fae67ab63db ("RDMA/rxe: Add support for Send/Recv/Write/Read with ODP"), v6.15+
  3/4: Fixes 8700e3e7c485 ("Soft RoCE driver"), v4.8+
  4/4: Fixes 8700e3e7c485 ("Soft RoCE driver"), v4.8+

Pre-f04d5b3d916c LTS branches carry the older wrap form
  iova > mr->ibmr.iova + mr->ibmr.length - length
instead of the current `iova + length > ...` shape.  Patches 1, 3, 4
will need a backport variant for those branches; I can provide on
request.

Tymbark7372 (4):
  RDMA/rxe: Fix u64 iova+length overflow in mr_check_range
  RDMA/rxe: Fix u64 iova+length overflow in rxe_check_pagefault
  RDMA/rxe: Fix u64 iova+resid overflow in duplicate_request
  RDMA/rxe: Fix u64 addr+length overflow in rxe_check_bind_mw

 drivers/infiniband/sw/rxe/rxe_mr.c   | 12 +++++++++---
 drivers/infiniband/sw/rxe/rxe_odp.c  | 10 ++++++++--
 drivers/infiniband/sw/rxe/rxe_resp.c | 11 ++++++++---
 drivers/infiniband/sw/rxe/rxe_mw.c   | 11 ++++++++---
 4 files changed, 33 insertions(+), 11 deletions(-)

--
Tymbark7372 <tymbark7372@proton.me>

[-- Attachment #2: 0003-RDMA-rxe-Fix-u64-iova-resid-overflow-in-duplicate_request.patch --]
[-- Type: application/octet-stream, Size: 2633 bytes --]

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tymbark7372 <tymbark7372@proton.me>
Date: Wed, 20 May 2026 19:34:00 +0200
Subject: [PATCH 3/4] RDMA/rxe: Fix u64 iova+resid overflow in duplicate_request

In the duplicate-READ handling of duplicate_request(), the third
clause of the bound check computes (iova + resid) and compares it
with (res->read.va_org + res->read.length).  iova is u64, resid is
u32 promoted to u64; the addition wraps modulo 2^64.  An attacker
setting reth_va = 0xFFFFFFFFFFFFFC00 and reth_len = 0x400 causes the
left-hand sum to wrap to 0 while the right-hand sum stays small, so
the check passes and res->read.va is later set to the wrap address on
replay.

Downstream of either bound check site in rxe_resp.c, read_reply
calls rxe_mr_copy() with the wrap iova, which re-traverses
mr_check_range() and rxe_mr_iova_to_index(), and rxe_mr_copy_xarray()
OOB-derefs page_info[huge_idx].  The primitive is the same as patch
1 of this series, reached via the RDMA_READ path on a duplicate
(retransmitted) request.

Use check_add_overflow() on both sides of the comparison.

Reproduced on v7.1.0-rc3 + KASAN with a single
ibv_post_send(IBV_WR_RDMA_READ) followed by a retransmit of the
identical packet, with the wrap iova above.  WARN at
rxe_mr_iova_to_index+0x135 followed by page-fault Oops in
rxe_mr_copy+0x20d on the READ path (rxe_receiver+0x3c70, distinct
from the WRITE offset rxe_receiver+0x6aa8 that the patch 1 trigger
reaches).

Fixes: 8700e3e7c485 ("Soft RoCE driver")
Cc: stable@vger.kernel.org # v4.8+
Reported-by: Tymbark7372 <tymbark7372@proton.me>
Signed-off-by: Tymbark7372 <tymbark7372@proton.me>
Assisted-by: Claude:claude-opus-4-7
---
 drivers/infiniband/sw/rxe/rxe_resp.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -1356,11 +1356,16 @@ static enum resp_states duplicate_request(struct rxe_qp *qp,
 			 */
 			u64 iova = reth_va(pkt);
 			u32 resid = reth_len(pkt);
+			u64 va_end_orig, va_end_new;

-			if (iova < res->read.va_org ||
+			if (check_add_overflow(res->read.va_org,
+					       (u64)res->read.length,
+					       &va_end_orig) ||
+			    check_add_overflow(iova, (u64)resid,
+					       &va_end_new) ||
+			    iova < res->read.va_org ||
 			    resid > res->read.length ||
-			    (iova + resid) > (res->read.va_org +
-					      res->read.length)) {
+			    va_end_new > va_end_orig) {
 				rc = RESPST_CLEANUP;
 				goto out;
 			}
--
2.43.0

[-- Attachment #3: 0004-RDMA-rxe-Fix-u64-addr-length-overflow-in-rxe_check_bind_mw.patch --]
[-- Type: application/octet-stream, Size: 2153 bytes --]

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tymbark7372 <tymbark7372@proton.me>
Date: Wed, 20 May 2026 19:34:00 +0200
Subject: [PATCH 4/4] RDMA/rxe: Fix u64 addr+length overflow in rxe_check_bind_mw

rxe_check_bind_mw() validates that a Type 2 memory window's range
[addr, addr + length) is contained within its parent MR's range
[mr->ibmr.iova, mr->ibmr.iova + mr->ibmr.length).  Both end-addition
sums wrap modulo 2^64.  An attacker can bind a memory window whose
nominal range exceeds the parent MR by wrapping the comparison sum
to a value below the parent's iova.

This is the same wrap class as patch 1 of this series; it was found
by sibling-site grep against the other rxe iova checks and is not on
the OOB-write path of the three primary bugs.  I have not
demonstrated a downstream OOB primitive that uses this specific
escape, so it is filed here as a defensive sibling fix rather than as
a separate exploitable bug.  Folding it into the same series keeps
the wrap-class fixes together.

Use check_add_overflow() on both ends.

Fixes: 8700e3e7c485 ("Soft RoCE driver")
Cc: stable@vger.kernel.org # v4.8+
Reported-by: Tymbark7372 <tymbark7372@proton.me>
Signed-off-by: Tymbark7372 <tymbark7372@proton.me>
Assisted-by: Claude:claude-opus-4-7
---
 drivers/infiniband/sw/rxe/rxe_mw.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
--- a/drivers/infiniband/sw/rxe/rxe_mw.c
+++ b/drivers/infiniband/sw/rxe/rxe_mw.c
@@ -120,9 +120,14 @@
 			return -EINVAL;
 		}
 	} else {
-		if (unlikely((wqe->wr.wr.mw.addr < mr->ibmr.iova) ||
-			     ((wqe->wr.wr.mw.addr + wqe->wr.wr.mw.length) >
-			      (mr->ibmr.iova + mr->ibmr.length)))) {
+		u64 mw_end, mr_end;
+
+		if (unlikely(check_add_overflow(wqe->wr.wr.mw.addr,
+						wqe->wr.wr.mw.length, &mw_end) ||
+			     check_add_overflow(mr->ibmr.iova,
+						mr->ibmr.length, &mr_end) ||
+			     wqe->wr.wr.mw.addr < mr->ibmr.iova ||
+			     mw_end > mr_end)) {
 			rxe_dbg_mw(mw,
 				"attempt to bind a VA MW outside of the MR\n");
 			return -EINVAL;
--
2.43.0

[-- Attachment #4: 0002-RDMA-rxe-Fix-u64-iova-length-overflow-in-rxe_check_pagefault.patch --]
[-- Type: application/octet-stream, Size: 2770 bytes --]

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tymbark7372 <tymbark7372@proton.me>
Date: Wed, 20 May 2026 19:34:00 +0200
Subject: [PATCH 2/4] RDMA/rxe: Fix u64 iova+length overflow in rxe_check_pagefault

rxe_check_pagefault() loops with the condition
"addr < iova + length" where iova is u64 and length is int.  The
addition is promoted to u64 and wraps modulo 2^64 when iova is near
U64_MAX.  With iova = 0xFFFFFFFFFFFFFC00 and length = 0x400 the sum
is 0; the loop body never executes; the function returns
need_fault = false; and the prefetch-fault check is bypassed.

Control then enters __rxe_odp_mr_copy(), which calls
rxe_odp_iova_to_index() on the wrap iova to obtain a huge index, and
dereferences umem_odp->map.pfn_list[huge_idx], an attacker-controlled
out-of-bounds slot.  hmm_pfn_to_page() resolves the read value to an
attacker-chosen struct page, after which memcpy lands at
kmap_local_page(that_page) + offset, yielding arbitrary kernel write.

Reject any iova/length pair that overflows by computing iova_end with
check_add_overflow() once before the loop and using it as the loop
bound.  A negative length is also rejected to avoid u64 promotion
masking the case.

Reproduced on v7.1.0-rc3 + KASAN with a single RDMA_WRITE against an
ODP-flagged MR; the kernel oopses in rxe_odp_mr_copy+0x205 with
RSI=0xfffffffffffffc00 (the wrap iova) and R13 holding the resolved
wrapped index.  A working LPE chain that uses this OOB primitive to
overwrite cred_jar slab pages was demonstrated end-to-end on the same
verification kernel.

Fixes: 2fae67ab63db ("RDMA/rxe: Add support for Send/Recv/Write/Read with ODP")
Cc: stable@vger.kernel.org # v6.15+
Reported-by: Tymbark7372 <tymbark7372@proton.me>
Signed-off-by: Tymbark7372 <tymbark7372@proton.me>
Assisted-by: Claude:claude-opus-4-7
---
 drivers/infiniband/sw/rxe/rxe_odp.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_odp.c b/drivers/infiniband/sw/rxe/rxe_odp.c
--- a/drivers/infiniband/sw/rxe/rxe_odp.c
+++ b/drivers/infiniband/sw/rxe/rxe_odp.c
@@ -127,13 +127,19 @@ static inline bool rxe_check_pagefault(struct ib_umem_odp *umem_odp, u64 iova,
 				       int length)
 {
 	bool need_fault = false;
-	u64 addr;
+	u64 addr, iova_end;
 	int idx;

+	if (length < 0 ||
+	    check_add_overflow(iova, (u64)length, &iova_end)) {
+		/* let the pagefault path reject a bogus iova/length */
+		return true;
+	}
+
 	addr = iova & (~(BIT(umem_odp->page_shift) - 1));

 	/* Skim through all pages that are to be accessed. */
-	while (addr < iova + length) {
+	while (addr < iova_end) {
 		idx = (addr - ib_umem_start(umem_odp)) >> umem_odp->page_shift;

 		if (!(umem_odp->map.pfn_list[idx] & HMM_PFN_VALID)) {
--
2.43.0

[-- Attachment #5: 0001-RDMA-rxe-Fix-u64-iova-length-overflow-in-mr_check_range.patch --]
[-- Type: application/octet-stream, Size: 2948 bytes --]

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tymbark7372 <tymbark7372@proton.me>
Date: Wed, 20 May 2026 19:34:00 +0200
Subject: [PATCH 1/4] RDMA/rxe: Fix u64 iova+length overflow in mr_check_range

In mr_check_range(), the IB_MR_TYPE_USER and IB_MR_TYPE_MEM_REG case
computes both iova + length and mr->ibmr.iova + mr->ibmr.length without
overflow check.  Both iova (u64) and length (size_t) are 64-bit on
64-bit platforms.  An attacker setting iova = 0xFFFFFFFFFFFFFC00 and
length = 0x400 wraps the sum to 0, so the bound check
"iova + length > mr->ibmr.iova + mr->ibmr.length" passes.

After the bypass, rxe_mr_iova_to_index() computes a huge index value;
WARN_ON(idx >= mr->nbuf) fires but does not abort, and
rxe_mr_copy_xarray() then dereferences page_info[huge_idx], an
attacker-controlled out-of-bounds slot.  In the RXE_TO_MR_OBJ
direction this becomes an OOB write of attacker payload bytes through
info->page + info->offset.

Use check_add_overflow() on both ends to reject any iova/length pair
that wraps.  Also explicitly scope the local declarations introduced
by the helper variables.

Reachable from any unprivileged local process with
/dev/infiniband/uverbs0 open (world-rw on distros that ship the
rdma-core udev rules) and from an unauthenticated remote peer over
UDP/4791 (RoCEv2) when the target rkey/QPN are known.  Reproduced on
v7.1.0-rc3 + KASAN with a single ibv_post_send(IBV_WR_RDMA_WRITE) and
the wrap iova above; the kernel oopses in rxe_mr_copy+0x20d after
WARN at rxe_mr_iova_to_index+0x135.

Site A in rxe_resp.c (check_rkey()) reaches mr_check_range() with
attacker iova as well, so this patch also closes that path; Site B
(duplicate_request, also in rxe_resp.c) has an independent inline
check that wraps and is fixed in patch 3 of this series.

Fixes: 8700e3e7c485 ("Soft RoCE driver")
Cc: stable@vger.kernel.org # v4.8+
Reported-by: Tymbark7372 <tymbark7372@proton.me>
Signed-off-by: Tymbark7372 <tymbark7372@proton.me>
Assisted-by: Claude:claude-opus-4-7
---
 drivers/infiniband/sw/rxe/rxe_mr.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -30,13 +30,19 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length)
 		return 0;

 	case IB_MR_TYPE_USER:
-	case IB_MR_TYPE_MEM_REG:
-		if (iova < mr->ibmr.iova ||
-		    iova + length > mr->ibmr.iova + mr->ibmr.length) {
+	case IB_MR_TYPE_MEM_REG: {
+		u64 iova_end, mr_end;
+
+		if (check_add_overflow(iova, length, &iova_end) ||
+		    check_add_overflow(mr->ibmr.iova, mr->ibmr.length,
+				       &mr_end) ||
+		    iova < mr->ibmr.iova ||
+		    iova_end > mr_end) {
 			rxe_dbg_mr(mr, "iova/length out of range\n");
 			return -EINVAL;
 		}
 		return 0;
+	}

 	default:
 		rxe_dbg_mr(mr, "mr type not supported\n");
--
2.43.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-05-25 20:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21 19:44 [PATCH 0/4] RDMA/rxe: Fix u64 iova-overflow family in MR/ODP/RESP/MW paths Tymbark7372
2026-05-21 19:44 ` [PATCH 1/4] RDMA/rxe: Fix u64 iova+length overflow in mr_check_range Tymbark7372
2026-05-22  4:44   ` Greg KH
2026-05-21 19:44 ` [PATCH 2/4] RDMA/rxe: Fix u64 iova+length overflow in rxe_check_pagefault Tymbark7372
2026-05-21 19:44 ` [PATCH 3/4] RDMA/rxe: Fix u64 iova+resid overflow in duplicate_request Tymbark7372
2026-05-21 19:44 ` [PATCH 4/4] RDMA/rxe: Fix u64 addr+length overflow in rxe_check_bind_mw Tymbark7372
2026-05-22  2:54 ` [PATCH 0/4] RDMA/rxe: Fix u64 iova-overflow family in MR/ODP/RESP/MW paths Zhu Yanjun
2026-05-25 11:15   ` Tymbark7372
2026-05-25 20:54     ` Zhu Yanjun
  -- strict thread matches above, loose matches on Subject: below --
2026-05-21 15:39 Tymbark7372
2026-05-21 15:46 ` Zhu Yanjun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox