From: Omar Ramadan <omar@blockcast.net>
To: Taehee Yoo <ap420073@gmail.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Simon Horman <horms@kernel.org>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Clark Williams <clrkwllms@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
linux-rt-devel@lists.linux.dev
Subject: [PATCH net v6 0/6] amt: relay tunnel lifetime, validation and request-path hardening
Date: Sat, 7 Nov 2026 00:49:29 +0000 [thread overview]
Message-ID: <20261107004935.2627329-1-omar@blockcast.net> (raw)
This series hardens AMT relay tunnel lifetime, validates gateway input, and
keeps unauthenticated Requests from consuming relay state. The problems
fixed by patches 3 and 4, and the pre-Query drop in patch 5, were found
during the AMT IPv6 outer transport work, which is not included here.
I am using the existing IPv4 AMT relay and gateway implementation in a
multicast delivery network, where gateways on access networks send IGMP/MLD
membership state through a relay to reach downstream receivers.
The first patch detaches the receive path before amt_dev_stop() tears down
events and tunnels, so no receive-path reader can queue work after the
teardown. The second closes the gc_wq re-arm use-after-free and makes
teardown safe for RCU readers and delayed group/source workers. The third
rejects Queries and Data from 0.0.0.0 before relay discovery and
revalidates deferred Queries. The fourth requires exactly four bytes for
IFLA_AMT_LOCAL_IP and IFLA_AMT_DISCOVERY_IP. The fifth makes pre-Query
drops visible, avoids counting successful reports as drops, and uses
concurrent-safe TX statistics. The sixth keeps Requests stateless,
authenticates Membership Updates and checks their IGMP/MLD message before
allocation, keys state by address and port, bounds per-source admission,
and silently drops failed endpoint admission.
Each commit message says how its problems were found. The problem in
patch 4 was triggered while writing an IPv6 selftest; the others were
found by review or code inspection.
Changes in v6 (patches 2-6 were v5's 1-5):
- New patch 1: clear the socket's sk_user_data before amt_dev_stop()'s
grace period, so no amt_rcv() can still queue event_wq or link a
tunnel after the teardown. Found by code inspection while reviewing
the changes below.
- Patch 2: run the deferred group/source GC directly instead of
flushing its work. flush_delayed_work() queues the work and waits for
it to run, which needs a free amt_wq active slot, so
amt_tunnel_expire() and the group GC, both amt_wq work, could deadlock
once every slot was held by such a waiter. amt_dev_stop() calls the
GC the same way. (Sashiko)
- Patch 2: amt_tunnel_expire() reads jiffies once (Sashiko), and reads
last_seen and marks the tunnel dead in one tunnel->lock section. The
Update path refreshes last_seen under that lock, once the encapsulated
message has passed its IGMP/MLD check, so an Update either keeps the
tunnel alive or finds it dead (Sashiko, raised on v5 5/5). An Update
never stores 0, which marks a tunnel no Update has refreshed.
- Patch 2: keep amt_group_work()'s loop braces, and order the
declarations the patch touches longest first.
- Patch 6: create or refresh tunnel state only once ip_mc_check_igmp()
or ipv6_mc_check_mld() has accepted the encapsulated message.
(Sashiko)
- Patch 6: the tunnel lookup skips dead tunnels and amt_update_tunnel()
retries once, so an Update that races amt_tunnel_expire() creates the
replacement instead of being dropped. (Sashiko)
- Patch 6: the Request path's per-source count skips dead tunnels too,
so a tunnel being expired no longer withholds a new endpoint's Query.
- Patch 6: drop the per-Update amt_update_relay_status() call, a no-op
since tunnel creation sets that status (Sashiko), and the last_seen 0
special case, since every tunnel is now stamped when it is created.
- Patch 6: retitled from "amt: harden relay authentication and
teardown"; its teardown changes moved to patch 2 in an earlier
revision. Its message now says why a refused Request gets no ICMP Host
Unreachable.
- Patches 2, 3, 5 and 6: correct commit-message and comment claims that
overstated or misdescribed the code, and say how each problem was
found without per-version history. Patch 4 is unchanged.
Changes in v5 (since the 2026-10-20 posting; v5 numbering, so its
patches 1-5 are v6's 2-6):
- Patch 1: flush the deferred group/source GC with flush_delayed_work()
instead of cancel_delayed_work_sync(). Both GC works re-arm only
themselves, so cancelling them on tunnel expiry or device stop stopped
periodic GC for good after the first expiry. The flush only reclaims
promptly; lifetime rests on RCU and the cleared owner pointers, and the
comment and changelog now say so.
- Patch 1: clear snode->gnode and gnode->tunnel_list with WRITE_ONCE().
Neither pointer is __rcu, so RCU_INIT_POINTER() drew two new sparse
errors.
- Patch 1: keep amt_group_work()'s single out: exit and move
rcu_read_unlock() below the label, instead of open-coding
rcu_read_unlock() and dev_put() at three exits. Every exit still
drops RCU and then the timer's device reference.
- Patch 5: drop the paragraph about tunnel liveness checks, which moved
to patch 1 in the previous revision, and fix one continuation-line
alignment.
- Patch 5: copy the secret generations in the Update path under a
seqcount, amt->key_seq, rather than under amt->lock, as the Sashiko
AI review of the 2026-10-15 posting suggested. Forged Updates now
take amt->lock only on PREEMPT_RT, to wait for a writer. Requests
still read key[0], nr_tunnels and max_tunnels in one O(1) amt->lock
section.
- Patch 5: say in the commit message why one address may hold at most
16 tunnels.
- All: state how each issue was found, and put Signed-off-by above the
"---" separator (it was below it in the previous posting, so git am
dropped it).
Testing: on base-commit below, each patch builds without new warnings
with W=1 C=1 (sparse) for IPv6=y, IPv6=n, PROVE_LOCKING and
PREEMPT_RT. With KASAN and lockdep enabled,
tools/testing/selftests/net/amt.sh passes (6/6) with no splats.
v5: https://lore.kernel.org/netdev/20261105125010.1107546-1-omar@blockcast.net/
v4 (mislabelled, 2026-10-20): https://lore.kernel.org/netdev/20261020002557.3984927-1-omar@blockcast.net/
v4 (re-posted 2026-10-15): https://lore.kernel.org/netdev/20261015220648.1545576-1-omar@blockcast.net/
v4: https://lore.kernel.org/netdev/20261013175407.947606-1-omar@blockcast.net/
v3: https://lore.kernel.org/netdev/20261012125943.558629-1-omar@blockcast.net/
v2: https://lore.kernel.org/netdev/20261009201455.1904698-1-omar@blockcast.net/
v1: https://lore.kernel.org/netdev/20261008003606.3666617-1-omar@blockcast.net/
Assisted-by: LLM
Omar Ramadan (6):
amt: stop receiving before amt_dev_stop() tears down its state
amt: fix use-after-free when a Membership Update re-arms a freed
tunnel
amt: reject a gateway Query or Data from 0.0.0.0 before a relay is
learned
amt: require an exact IPv4-sized IFLA_AMT_{LOCAL,DISCOVERY}_IP
amt: make pre-query report drops visible
amt: create relay tunnels only from authenticated Updates
drivers/net/amt.c | 623 +++++++++++++++++++++++++++++++++++-----------
include/net/amt.h | 31 ++-
2 files changed, 504 insertions(+), 150 deletions(-)
base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
--
2.43.0
next reply other threads:[~2026-11-07 0:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 0:49 Omar Ramadan [this message]
2026-11-07 0:49 ` [PATCH net v6 1/6] amt: stop receiving before amt_dev_stop() tears down its state Omar Ramadan
2026-11-07 0:49 ` [PATCH net v6 2/6] amt: fix use-after-free when a Membership Update re-arms a freed tunnel Omar Ramadan
2026-11-07 0:49 ` [PATCH net v6 3/6] amt: reject a gateway Query or Data from 0.0.0.0 before a relay is learned Omar Ramadan
2026-11-07 0:49 ` [PATCH net v6 4/6] amt: require an exact IPv4-sized IFLA_AMT_{LOCAL,DISCOVERY}_IP Omar Ramadan
2026-11-07 0:49 ` [PATCH net v6 5/6] amt: make pre-query report drops visible Omar Ramadan
2026-11-07 0:49 ` [PATCH net v6 6/6] amt: create relay tunnels only from authenticated Updates Omar Ramadan
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=20261107004935.2627329-1-omar@blockcast.net \
--to=omar@blockcast.net \
--cc=andrew+netdev@lunn.ch \
--cc=ap420073@gmail.com \
--cc=bigeasy@linutronix.de \
--cc=clrkwllms@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rostedt@goodmis.org \
/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
all inboxes | Powered by JetHome®