From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Florian Westphal <fw@strlen.de>
Cc: allfox wy <allfoxwy@gmail.com>, netfilter@vger.kernel.org
Subject: Re: [regression] Completely editing packet should be allowed.
Date: Fri, 6 Nov 2026 12:46:55 +0100 [thread overview]
Message-ID: <au2-LzjOKKSKIu6C@chamomile> (raw)
In-Reply-To: <au1gtHLku32CeSVC@strlen.de>
On Fri, Nov 06, 2026 at 06:08:04AM +0100, Florian Westphal wrote:
> allfox wy <allfoxwy@gmail.com> wrote:
> > I have a homebrew cipher program using libnetfilter_queue, which would
> > intercept certain IP in IP packets via iptables' NFQUEUE target, edit
> > them ( completely ) then put them back to OS for further processing.
> >
> > Received packets would be redirected via RAW table ( which would
> > happen before CONNTRACK ) , while sending packets would be redirected
> > via MANGLE table POSTROUTING chain ( they are leaving the host, no
> > longer need to be CONTRACKed ).
> >
> > The edit is to transform the entire inner packet with a cipher. By
> > entire, I mean including the inner header hidden and the original
> > length would change.
> > The receiving host would decipher it back to normal IP in IP packet in
> > RAW table.
> >
> > This would form a transparent tunnel and had worked for years.
> >
> > However recently I tried to switch from Linux 6.18 LTS to 7.4-rc1 ( in
> > favour of tcp_roccet ), my homebrew stopped working.
> > There is no error message anywhere, all libnetfilter_queue functions
> > return success, I could see the packet, I could edit it, I could send
> > the verdict. Just after my edit, the packet would fade into void
> > somehow. Like the host never had it.
> >
> > So I did a bisect, it comes to
> > 112e447d17f78d08485b3076a8baa1dfb9794bd8 is the first bad commit:
> > - netfilter: validate L4 headers after userspace packet writes.
> >
> > I don't really get the idea of the situation here:
> > - Freestyle packet via libnetfilter_queue is no longer supported?
>
> It has to be restricted.
>
> > - What is the rule of validation? What can be edited and what can't be touched?
>
> ATM: ip saddr/daddr can change, l4 port numbers can change.
> No insertion of extension headers or add/removal of IP options.
>
> Could be supported but requires recomputations of internal data in the
> kernel.
>
> > I still feel making a cipher should be a valid use case for
> > libnetfilter_queue. ( Which would replace the entire inner packet of
> > IP in IP encapsulation, so any validation on the inner content would
> > fail )
> > The whole point of libnetfilter_queue is giving userspace a way to
> > inspect/edit the packet. When all function calls success and the
> > userspace say "verdict, allow" then the system silently dropping the
> > packet into void does not sound very logical to me.
> >
> > So that
> > - I vote for reverting 112e447d . As in my view, it would kill a valid
> > use case of libnetfilter_queue and NFQUEUE target.
>
> We really can't, no restrictions allow kernel crash. But its likely
> your use case can be made to work again.
>
> Wild guess: you're changing the l4 protocol number and the postrouting
> hook reinject fails because of proto mismatch wrt. what conntrack picked
> up?
>
> diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
> index 90d887546f7d..d2f83004e156 100644
> --- a/net/netfilter/nfnetlink_queue.c
> +++ b/net/netfilter/nfnetlink_queue.c
> @@ -1229,10 +1229,8 @@ static bool nfqnl_validate_l4(const u8 *data, unsigned int data_len,
> const struct nf_conn *ct;
>
> ct = nf_ct_get(e->skb, &ctinfo);
> - if (ct && !nf_ct_is_template(ct)) {
> - if (fragment || nf_ct_protonum(ct) != proto)
> - return false;
> - }
> + if (ct && nf_ct_protonum(ct) != proto)
> + nf_reset_ct(e->skb);
I agree ct should be dropping in such a change, because this ct does
not represent this skb anymore.
> #endif
>
> If that doesn't help, can you either see if you can figure out where the
> validation fails, or, alternatively, describe what header modifications
> your userspace program is doing?
>
next prev parent reply other threads:[~2026-11-06 11:47 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 19:02 [regression] Completely editing packet should be allowed allfox wy
2026-11-06 5:08 ` Florian Westphal
2026-11-06 11:46 ` Pablo Neira Ayuso [this message]
2026-11-07 8:04 ` allfox wy
2026-11-07 8:10 ` allfox wy
2026-11-09 10:25 ` Pablo Neira Ayuso
2026-11-09 10:49 ` Pablo Neira Ayuso
2026-11-09 14:19 ` Florian Westphal
2026-11-09 15:45 ` allfox wy
2026-11-09 16:19 ` Florian Westphal
2026-11-09 16:44 ` allfox wy
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=au2-LzjOKKSKIu6C@chamomile \
--to=pablo@netfilter.org \
--cc=allfoxwy@gmail.com \
--cc=fw@strlen.de \
--cc=netfilter@vger.kernel.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