]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
netfilter: nf_conntrack_gre: fix gre keymap list corruption
authorFlorian Westphal <fw@strlen.de>
Thu, 14 May 2026 12:21:57 +0000 (14:21 +0200)
committerFlorian Westphal <fw@strlen.de>
Fri, 22 May 2026 10:28:46 +0000 (12:28 +0200)
commit47980b6dbf83961eec1c1363ea986e9c06ff8054
tree68590d574ebf8f7f078580998bbf04fb62f37d01
parent92170e6afe927ab2792a3f71902845789c8e31b1
netfilter: nf_conntrack_gre: fix gre keymap list corruption

Quoting reporter:
  A race between GRE keymap insertion and destruction can corrupt the
  kernel list or use a freed object. `nf_ct_gre_keymap_add()` publishes a
  new keymap pointer before the embedded `list_head` is linked, while
  `nf_ct_gre_keymap_destroy()` can concurrently delete and free that
  same object. An unprivileged user can reach this through the PPTP
  conntrack helper by racing PPTP control messages or helper teardown,
  leading to KASAN-detectable list corruption/UAF in kernel context.

 ## Root Cause Analysis
 `exp_gre()` installs GRE expectations for a PPTP control flow and then
  adds two GRE keymap entries [..]

 The add path publishes `ct_pptp_info->keymap[dir]` before linking the
 embedded list node [..]
 Concurrent teardown deletes that partially initialized object.

Make add/destroy symmetric: install both, destroy both while under lock.

Furthermore, we should refuse to publish a new mapping in case ct is going
away, else we may leak the allocation.

The "retrans" detection is strange:  existing mapping is checked for key
equality with the new mapping, then for "is on the list" via list walk.

But I can't see how an existing keymap entry can be NOT on list.

Change this to only check if we're asked to map same tuple again -- if so,
   skip re-install, else signal failure.

Last, add a bug trap for the keymap list; it has to be empty when namespace
is going away.

Reported-by: Leo Lin <leo@depthfirst.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
include/linux/netfilter/nf_conntrack_proto_gre.h
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nf_conntrack_proto_gre.c