* Re: [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi
[not found] <CAFRy_Hg8O9smcwzWTdBn6j6NLwv+8vBXKtm2KTsOoG1CjxC2Dg@mail.gmail.com>
@ 2026-04-29 7:08 ` Steffen Klassert
2026-04-29 7:21 ` Greg Kroah-Hartman
2026-04-29 8:29 ` Michal Kosiorek
0 siblings, 2 replies; 6+ messages in thread
From: Steffen Klassert @ 2026-04-29 7:08 UTC (permalink / raw)
To: Michal Kosiorek
Cc: Herbert Xu, David S. Miller, Eric Dumazet, Jakub Kicinski, Abeni,
Simon Horman, Greg Kroah-Hartman, linux-kernel
On Tue, Apr 28, 2026 at 09:53:45AM +0200, Michal Kosiorek wrote:
...
>
> Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
> Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
> Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
Please add a 'Fixes:' tag so the patch can be backported
to the stable trees.
> ---
> net/xfrm/xfrm_state.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
> @@ -758,16 +758,16 @@ int __xfrm_state_delete(struct xfrm_state *x)
>
> spin_lock(&net->xfrm.xfrm_state_lock);
> list_del(&x->km.all);
> - hlist_del_rcu(&x->bydst);
> - hlist_del_rcu(&x->bysrc);
> - if (x->km.seq)
> - hlist_del_rcu(&x->byseq);
> + hlist_del_init_rcu(&x->bydst);
> + hlist_del_init_rcu(&x->bysrc);
> + if (!hlist_unhashed(&x->byseq))
> + hlist_del_init_rcu(&x->byseq);
> if (!hlist_unhashed(&x->state_cache))
> hlist_del_rcu(&x->state_cache);
> if (!hlist_unhashed(&x->state_cache_input))
> hlist_del_rcu(&x->state_cache_input);
>
> - if (x->id.spi)
> - hlist_del_rcu(&x->byspi);
> + if (!hlist_unhashed(&x->byspi))
> + hlist_del_init_rcu(&x->byspi);
> net->xfrm.state_num--;
> xfrm_nat_keepalive_state_updated(x);
> spin_unlock(&net->xfrm.xfrm_state_lock);
This does not allpy to the ipsec tree. Please
rebase on the ipsec tree and resend.
Thanks!
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi
2026-04-29 7:08 ` [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi Steffen Klassert
@ 2026-04-29 7:21 ` Greg Kroah-Hartman
2026-04-29 8:29 ` Michal Kosiorek
1 sibling, 0 replies; 6+ messages in thread
From: Greg Kroah-Hartman @ 2026-04-29 7:21 UTC (permalink / raw)
To: Steffen Klassert
Cc: Michal Kosiorek, Herbert Xu, David S. Miller, Eric Dumazet,
Jakub Kicinski, Abeni, Simon Horman, linux-kernel
On Wed, Apr 29, 2026 at 09:08:51AM +0200, Steffen Klassert wrote:
> On Tue, Apr 28, 2026 at 09:53:45AM +0200, Michal Kosiorek wrote:
> ...
> >
> > Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
> > Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
> > Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
>
> Please add a 'Fixes:' tag so the patch can be backported
> to the stable trees.
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read:
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.
</formletter>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi
2026-04-29 7:08 ` [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi Steffen Klassert
2026-04-29 7:21 ` Greg Kroah-Hartman
@ 2026-04-29 8:29 ` Michal Kosiorek
2026-04-29 8:42 ` Steffen Klassert
1 sibling, 1 reply; 6+ messages in thread
From: Michal Kosiorek @ 2026-04-29 8:29 UTC (permalink / raw)
To: Steffen Klassert
Cc: Herbert Xu, David S. Miller, Eric Dumazet, Jakub Kicinski, Abeni,
Simon Horman, Greg KH, sd, netdev, linux-kernel, stable
v2 addresses your two points:
- Added Fixes: tags (fe9f1d8779cb for byseq, 7b4dc3600e48 for byspi).
- Rebased on ipsec.git master (HEAD fa90a3145c03), `git apply --check`
clean. Same hunk applies to torvalds/master without changes.
Also added `Cc: stable@vger.kernel.org` per stable-kernel-rules.html
Option 1, since the Fixes: tags otherwise leave AUTOSEL doing the
disambiguation work alone.
Patch follows.
---
KASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s
hlist_del_rcu calls under syzkaller load on linux-6.12.y stable
(reproduced on 6.12.47, also reachable via the same code path on
torvalds/master and on the ipsec tree). Nine unique signatures cluster
in the xfrm_state lifecycle, the load-bearing one being:
BUG: KASAN: slab-use-after-free in __hlist_del
include/linux/list.h:990 [inline]
BUG: KASAN: slab-use-after-free in hlist_del_rcu
include/linux/rculist.h:516 [inline]
BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c
Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435
Workqueue: netns cleanup_net
Call Trace:
__hlist_del / hlist_del_rcu
__xfrm_state_delete
xfrm_state_delete
xfrm_state_flush
xfrm_state_fini
ops_exit_list
cleanup_net
The other observed signatures hit the same slab object from
__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB
write variant of __xfrm_state_delete, all on the byseq/byspi
hash chains.
__xfrm_state_delete() guards its byseq and byspi unhashes with
value-based predicates:
if (x->km.seq)
hlist_del_rcu(&x->byseq);
if (x->id.spi)
hlist_del_rcu(&x->byspi);
while everywhere else in the file (e.g. state_cache, state_cache_input)
the safer hlist_unhashed() check is used. xfrm_alloc_spi() sets
x->id.spi = newspi inside xfrm_state_lock and then immediately inserts
into byspi, but a path that observes x->id.spi != 0 outside of
xfrm_state_lock can still skip-or-hit the byspi unhash inconsistently
with whether x is actually on the list. The same holds for x->km.seq
versus byseq, and the bydst/bysrc unhashes have no predicate at all,
so a second __xfrm_state_delete() on the same object writes through
LIST_POISON pprev.
The defensive change here:
- Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,
bysrc, byseq and byspi so a second deletion is a no-op rather
than a write through LIST_POISON pprev. The byseq/byspi nodes
are already initialised in xfrm_state_alloc().
- Test hlist_unhashed() rather than the value predicate for
byseq/byspi, so the unhash decision tracks list state rather than
mutable scalar fields.
Empirical verification: applied this patch on top of v6.12.47, rebuilt,
and re-ran the same syzkaller harness for 1h16m on a previously-crashy
configuration that produced ~100 hits each of slab-use-after-free
Read in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in
__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at
~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo
confirms the xfrm_state slab is actively allocated and freed during
the run (~143 KiB resident), so the fuzzer is still exercising those
code paths -- they just no longer crash.
Reproduction:
- Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV
- syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db
- 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal
- 9 unique signatures collected in ~9h, all within xfrm_state
lifecycle
Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
Fixes: 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to
the SPI hash.")
Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
---
net/xfrm/xfrm_state.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1748d374abca..686014d39429 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -818,17 +818,17 @@ int __xfrm_state_delete(struct xfrm_state *x)
spin_lock(&net->xfrm.xfrm_state_lock);
list_del(&x->km.all);
- hlist_del_rcu(&x->bydst);
- hlist_del_rcu(&x->bysrc);
- if (x->km.seq)
- hlist_del_rcu(&x->byseq);
+ hlist_del_init_rcu(&x->bydst);
+ hlist_del_init_rcu(&x->bysrc);
+ if (!hlist_unhashed(&x->byseq))
+ hlist_del_init_rcu(&x->byseq);
if (!hlist_unhashed(&x->state_cache))
hlist_del_rcu(&x->state_cache);
if (!hlist_unhashed(&x->state_cache_input))
hlist_del_rcu(&x->state_cache_input);
- if (x->id.spi)
- hlist_del_rcu(&x->byspi);
+ if (!hlist_unhashed(&x->byspi))
+ hlist_del_init_rcu(&x->byspi);
net->xfrm.state_num--;
xfrm_nat_keepalive_state_updated(x);
spin_unlock(&net->xfrm.xfrm_state_lock);
--
2.54.0
śr., 29 kwi 2026 o 09:08 Steffen Klassert
<steffen.klassert@secunet.com> napisał(a):
>
> On Tue, Apr 28, 2026 at 09:53:45AM +0200, Michal Kosiorek wrote:
> ...
> >
> > Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
> > Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
> > Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
>
> Please add a 'Fixes:' tag so the patch can be backported
> to the stable trees.
>
> > ---
> > net/xfrm/xfrm_state.c | 12 ++++++------
> > 1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> > --- a/net/xfrm/xfrm_state.c
> > +++ b/net/xfrm/xfrm_state.c
> > @@ -758,16 +758,16 @@ int __xfrm_state_delete(struct xfrm_state *x)
> >
> > spin_lock(&net->xfrm.xfrm_state_lock);
> > list_del(&x->km.all);
> > - hlist_del_rcu(&x->bydst);
> > - hlist_del_rcu(&x->bysrc);
> > - if (x->km.seq)
> > - hlist_del_rcu(&x->byseq);
> > + hlist_del_init_rcu(&x->bydst);
> > + hlist_del_init_rcu(&x->bysrc);
> > + if (!hlist_unhashed(&x->byseq))
> > + hlist_del_init_rcu(&x->byseq);
> > if (!hlist_unhashed(&x->state_cache))
> > hlist_del_rcu(&x->state_cache);
> > if (!hlist_unhashed(&x->state_cache_input))
> > hlist_del_rcu(&x->state_cache_input);
> >
> > - if (x->id.spi)
> > - hlist_del_rcu(&x->byspi);
> > + if (!hlist_unhashed(&x->byspi))
> > + hlist_del_init_rcu(&x->byspi);
> > net->xfrm.state_num--;
> > xfrm_nat_keepalive_state_updated(x);
> > spin_unlock(&net->xfrm.xfrm_state_lock);
>
> This does not allpy to the ipsec tree. Please
> rebase on the ipsec tree and resend.
>
> Thanks!
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi
2026-04-29 8:29 ` Michal Kosiorek
@ 2026-04-29 8:42 ` Steffen Klassert
2026-04-29 8:54 ` [PATCH ipsec v2] xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete Michal Kosiorek
0 siblings, 1 reply; 6+ messages in thread
From: Steffen Klassert @ 2026-04-29 8:42 UTC (permalink / raw)
To: Michal Kosiorek
Cc: Herbert Xu, David S. Miller, Eric Dumazet, Jakub Kicinski, Abeni,
Simon Horman, Greg KH, sd, netdev, linux-kernel, stable
On Wed, Apr 29, 2026 at 10:29:10AM +0200, Michal Kosiorek wrote:
...
>
> Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
> Fixes: 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to
> the SPI hash.")
> Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
> Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
> ---
> net/xfrm/xfrm_state.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> index 1748d374abca..686014d39429 100644
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
> @@ -818,17 +818,17 @@ int __xfrm_state_delete(struct xfrm_state *x)
>
> spin_lock(&net->xfrm.xfrm_state_lock);
> list_del(&x->km.all);
> - hlist_del_rcu(&x->bydst);
> - hlist_del_rcu(&x->bysrc);
> - if (x->km.seq)
> - hlist_del_rcu(&x->byseq);
> + hlist_del_init_rcu(&x->bydst);
> + hlist_del_init_rcu(&x->bysrc);
> + if (!hlist_unhashed(&x->byseq))
> + hlist_del_init_rcu(&x->byseq);
> if (!hlist_unhashed(&x->state_cache))
> hlist_del_rcu(&x->state_cache);
> if (!hlist_unhashed(&x->state_cache_input))
> hlist_del_rcu(&x->state_cache_input);
>
> - if (x->id.spi)
> - hlist_del_rcu(&x->byspi);
> + if (!hlist_unhashed(&x->byspi))
> + hlist_del_init_rcu(&x->byspi);
> net->xfrm.state_num--;
> xfrm_nat_keepalive_state_updated(x);
> spin_unlock(&net->xfrm.xfrm_state_lock);
This looks still odd, the indentation seems to be wrong.
It does not apply, maybe your mail client malformed
the patch.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH ipsec v2] xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete
2026-04-29 8:42 ` Steffen Klassert
@ 2026-04-29 8:54 ` Michal Kosiorek
2026-04-30 7:57 ` Steffen Klassert
0 siblings, 1 reply; 6+ messages in thread
From: Michal Kosiorek @ 2026-04-29 8:54 UTC (permalink / raw)
To: Steffen Klassert
Cc: Herbert Xu, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Greg Kroah-Hartman, Sabrina Dubroca,
netdev, linux-kernel, stable
KASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s
hlist_del_rcu calls under syzkaller load on linux-6.12.y stable
(reproduced on 6.12.47, also reachable via the same code path on
torvalds/master and on the ipsec tree). Nine unique signatures cluster
in the xfrm_state lifecycle, the load-bearing one being:
BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]
BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]
BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c
Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435
Workqueue: netns cleanup_net
Call Trace:
__hlist_del / hlist_del_rcu
__xfrm_state_delete
xfrm_state_delete
xfrm_state_flush
xfrm_state_fini
ops_exit_list
cleanup_net
The other observed signatures hit the same slab object from
__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB
write variant of __xfrm_state_delete, all on the byseq/byspi
hash chains.
__xfrm_state_delete() guards its byseq and byspi unhashes with
value-based predicates:
if (x->km.seq)
hlist_del_rcu(&x->byseq);
if (x->id.spi)
hlist_del_rcu(&x->byspi);
while everywhere else in the file (e.g. state_cache, state_cache_input)
the safer hlist_unhashed() check is used. xfrm_alloc_spi() sets
x->id.spi = newspi inside xfrm_state_lock and then immediately inserts
into byspi, but a path that observes x->id.spi != 0 outside of
xfrm_state_lock can still skip-or-hit the byspi unhash inconsistently
with whether x is actually on the list. The same holds for x->km.seq
versus byseq, and the bydst/bysrc unhashes have no predicate at all,
so a second __xfrm_state_delete() on the same object writes through
LIST_POISON pprev.
The defensive change here:
- Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,
bysrc, byseq and byspi so a second deletion is a no-op rather
than a write through LIST_POISON pprev. The byseq/byspi nodes
are already initialised in xfrm_state_alloc().
- Test hlist_unhashed() rather than the value predicate for
byseq/byspi, so the unhash decision tracks list state rather than
mutable scalar fields.
Empirical verification: applied this patch on top of v6.12.47, rebuilt,
and re-ran the same syzkaller harness for 1h16m on a previously-crashy
configuration that produced ~100 hits each of slab-use-after-free
Read in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in
__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at
~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo
confirms the xfrm_state slab is actively allocated and freed during
the run (~143 KiB resident), so the fuzzer is still exercising those
code paths -- they just no longer crash.
Reproduction:
- Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV
- syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db
- 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal
- 9 unique signatures collected in ~9h, all within xfrm_state
lifecycle
Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
Fixes: 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to the SPI hash.")
Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
---
Resending v2 via git send-email -- the previous post had been sent
through Gmail's web client which stripped all tabs from the diff
hunk and made the patch un-applyable. Apologies for the noise. No
other changes versus the prior v2 send.
net/xfrm/xfrm_state.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1748d374abca..686014d39429 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -818,17 +818,17 @@ int __xfrm_state_delete(struct xfrm_state *x)
spin_lock(&net->xfrm.xfrm_state_lock);
list_del(&x->km.all);
- hlist_del_rcu(&x->bydst);
- hlist_del_rcu(&x->bysrc);
- if (x->km.seq)
- hlist_del_rcu(&x->byseq);
+ hlist_del_init_rcu(&x->bydst);
+ hlist_del_init_rcu(&x->bysrc);
+ if (!hlist_unhashed(&x->byseq))
+ hlist_del_init_rcu(&x->byseq);
if (!hlist_unhashed(&x->state_cache))
hlist_del_rcu(&x->state_cache);
if (!hlist_unhashed(&x->state_cache_input))
hlist_del_rcu(&x->state_cache_input);
- if (x->id.spi)
- hlist_del_rcu(&x->byspi);
+ if (!hlist_unhashed(&x->byspi))
+ hlist_del_init_rcu(&x->byspi);
net->xfrm.state_num--;
xfrm_nat_keepalive_state_updated(x);
spin_unlock(&net->xfrm.xfrm_state_lock);
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH ipsec v2] xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete
2026-04-29 8:54 ` [PATCH ipsec v2] xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete Michal Kosiorek
@ 2026-04-30 7:57 ` Steffen Klassert
0 siblings, 0 replies; 6+ messages in thread
From: Steffen Klassert @ 2026-04-30 7:57 UTC (permalink / raw)
To: Michal Kosiorek
Cc: Herbert Xu, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Greg Kroah-Hartman, Sabrina Dubroca,
netdev, linux-kernel, stable
On Wed, Apr 29, 2026 at 10:54:51AM +0200, Michal Kosiorek wrote:
...
>
> Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
> Fixes: 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to the SPI hash.")
> Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
> Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
Applied, thanks Michal!
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-30 7:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CAFRy_Hg8O9smcwzWTdBn6j6NLwv+8vBXKtm2KTsOoG1CjxC2Dg@mail.gmail.com>
2026-04-29 7:08 ` [PATCH] xfrm: protect __xfrm_state_delete against double-unhash of byseq/byspi Steffen Klassert
2026-04-29 7:21 ` Greg Kroah-Hartman
2026-04-29 8:29 ` Michal Kosiorek
2026-04-29 8:42 ` Steffen Klassert
2026-04-29 8:54 ` [PATCH ipsec v2] xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete Michal Kosiorek
2026-04-30 7:57 ` Steffen Klassert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox