netfilter: nf_queue: Don't recompute the hook_list head
Subsystems (3)
PATCH 1/1 netfilter: nf_queue: Don't recompute the hook_list head
If someone sends packets from one of the netdevice ingress hooks to the a userspace queue, and then userspace later accepts the packet, the netfilter code can enter an infinite loop as the list head will never be found.
Pass in the saved list_head to avoid this.
--- net/netfilter/nf_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_queue.c +1 -1
@@ -213,7 +213,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)if (verdict ==NF_ACCEPT ) { next_hook: - verdict =nf_iterate (&nf_hooks[entry->state.pf][entry->state.hook], + verdict =nf_iterate (entry->state.hook_list, skb, &entry->state, &elem); }
Signature · 4 lines
2.2.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
Pablo Neira Ayuso
maintainerQuoted 7 lines · Eric W. Biederman
If someone sends packets from one of the netdevice ingress hooks to the a userspace queue, and then userspace later accepts the packet, the netfilter code can enter an infinite loop as the list head will never be found.
Pass in the saved
list_headto avoid this.
There is no userspace queueing for netdevice yet, so this can be route through nf-next. Thanks.
Quoted 21 lines
Signed-off-by "Eric W. Biederman" <[email protected]>--- net/netfilter/nf_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)net/netfilter/nf_queue.c +1
-1@@ -213,7 +213,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)if (verdict ==NF_ACCEPT ) { next_hook: - verdict =nf_iterate (&nf_hooks[entry->state.pf][entry->state.hook], + verdict =nf_iterate (entry->state.hook_list, skb, &entry->state, &elem); }Signature · 1 line
2.2.1
Quoted 11 lines · Pablo Neira Ayuso
Quoted 7 lines · Eric W. Biederman
If someone sends packets from one of the netdevice ingress hooks to the a userspace queue, and then userspace later accepts the packet, the netfilter code can enter an infinite loop as the list head will never be found.
Pass in the saved
list_headto avoid this.There is no userspace queueing for netdevice yet, so this can be route through nf-next. Thanks.
*scratches head* the netdevice queueing is in the netfilter core.
netfilter_ingress calls nf_hook_slow. The queuing happens in nf_hook_slow if anything returns the verdict queue it.
This patch applies to Linus's tree.
So how in the world does this not need to be ported to 4.1?
Quoted 18 lines
Quoted 18 lines
Signed-off-by "Eric W. Biederman" <[email protected]>--- net/netfilter/nf_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)net/netfilter/nf_queue.c +1
-1@@ -213,7 +213,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)if (verdict ==NF_ACCEPT ) { next_hook: - verdict =nf_iterate (&nf_hooks[entry->state.pf][entry->state.hook], + verdict =nf_iterate (entry->state.hook_list, skb, &entry->state, &elem); }
Quoted 3 lines
Quoted 3 lines
Signature · 1 line
2.2.1
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
Pablo Neira Ayuso
maintainerQuoted 14 lines · Eric W. Biederman
Quoted 11 lines · Pablo Neira Ayuso
Quoted 7 lines · Eric W. Biederman
If someone sends packets from one of the netdevice ingress hooks to the a userspace queue, and then userspace later accepts the packet, the netfilter code can enter an infinite loop as the list head will never be found.
Pass in the saved
list_headto avoid this.There is no userspace queueing for netdevice yet, so this can be route through nf-next. Thanks.
Quoted 8 lines
*scratches head* the netdevice queueing is in the netfilter core.
netfilter_ingresscallsnf_hook_slow. The queuing happens innf_hook_slowif anything returns the verdict queue it.This patch applies to Linus's tree.
So how in the world does this not need to be ported to 4.1?
There is no nfnetlink_queue support for the netdev family at this moment, so this can't be triggered unless you use an out of tree module.
I have a patch here to add a static key to disable userspace queueing per family using a static key so that part would be basically inactive.
But if you really want to see this in 4.1, no problem, please just let me know and I'll pass it to David, as I said it's basically not resolving any urgent problem so this is not harming.
Thank you.
Quoted 28 lines · Pablo Neira Ayuso
Quoted 14 lines · Eric W. Biederman
Quoted 11 lines · Pablo Neira Ayuso
Quoted 7 lines · Eric W. Biederman
If someone sends packets from one of the netdevice ingress hooks to the a userspace queue, and then userspace later accepts the packet, the netfilter code can enter an infinite loop as the list head will never be found.
Pass in the saved
list_headto avoid this.There is no userspace queueing for netdevice yet, so this can be route through nf-next. Thanks.
Quoted 8 lines
*scratches head* the netdevice queueing is in the netfilter core.
netfilter_ingresscallsnf_hook_slow. The queuing happens innf_hook_slowif anything returns the verdict queue it.This patch applies to Linus's tree.
So how in the world does this not need to be ported to 4.1?
There is no
nfnetlink_queuesupport for the netdev family at this moment, so this can't be triggered unless you use an out of tree module.
Quoted 7 lines
I have a patch here to add a static key to disable userspace queueing per family using a static key so that part would be basically inactive.
But if you really want to see this in 4.1, no problem, please just let me know and I'll pass it to David, as I said it's basically not resolving any urgent problem so this is not harming.
So I have read through the code and I simply do not see anywhere that would prevent code in nft_queue to be called on a per netdevice chain, or where in nfqnl_enqueue_packet we would decided not to queue the packet.
Could you please point me to what in the code makes this code path impossible to use?
Right now it looks like something that is triggerable in 4.1.
Eric
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
Pablo Neira Ayuso
maintainerQuoted 1 line · Eric W. Biederman
Pablo Neira Ayuso <[email protected]> writes:
[...]
Quoted 12 lines
Quoted 11 lines
There is no
nfnetlink_queuesupport for the netdev family at this moment, so this can't be triggered unless you use an out of tree module.I have a patch here to add a static key to disable userspace queueing per family using a static key so that part would be basically inactive.
But if you really want to see this in 4.1, no problem, please just let me know and I'll pass it to David, as I said it's basically not resolving any urgent problem so this is not harming.
Quoted 7 lines
So I have read through the code and I simply do not see anywhere that would prevent code in
nft_queueto be called on a per netdevice chain, or where innfqnl_enqueue_packetwe would decided not to queue the packet.Could you please point me to what in the code makes this code path impossible to use?
int nf_queue(struct sk_buff *skb,
struct nf_hook_ops *elem,
struct nf_hook_state *state,
unsigned int queuenum)
{
const struct nf_afinfo *afinfo;
...
afinfo = nf_get_afinfo(state->pf);
if (!afinfo)
goto err_unlock;
...
}There is no afinfo for NFPROTO_NETDEV, so the packet the packet will be dropped.
Therefore, there is no way nf_reinject() can be called neither for bridge, arp, inet and netdev at this moment.
I have a patch here to restrict this easily in nft_queue so the user knows this can't be used at configuration time.
Quoted 38 lines · Pablo Neira Ayuso
Quoted 1 line · Eric W. Biederman
Pablo Neira Ayuso <[email protected]> writes:
[...]
Quoted 12 lines
Quoted 11 lines
There is no
nfnetlink_queuesupport for the netdev family at this moment, so this can't be triggered unless you use an out of tree module.I have a patch here to add a static key to disable userspace queueing per family using a static key so that part would be basically inactive.
But if you really want to see this in 4.1, no problem, please just let me know and I'll pass it to David, as I said it's basically not resolving any urgent problem so this is not harming.
Quoted 7 lines
So I have read through the code and I simply do not see anywhere that would prevent code in
nft_queueto be called on a per netdevice chain, or where innfqnl_enqueue_packetwe would decided not to queue the packet.Could you please point me to what in the code makes this code path impossible to use?
int nf_queue(struct
sk_buff*skb,
structnf_hook_ops*elem,
structnf_hook_state*state,
unsigned int queuenum){ const struct nf_afinfo *afinfo; ... afinfo = nf_get_afinfo(state->pf); if (!afinfo) goto err_unlock; ... }
Quoted 8 lines
There is no afinfo for
NFPROTO_NETDEV, so the packet the packet will be dropped.Therefore, there is no way
nf_reinject()can be called neither for bridge, arp, inet and netdev at this moment.I have a patch here to restrict this easily in
nft_queueso the user knows this can't be used at configuration time.
Subtle but it I see it now. Thank you.
With only nf_register_afinfo calls for ipv4 and ipv6 present in the kernel it is clear that we can not run into trouble in the nedev ingress path, and so my fix clearly does not need to be backported.
Eric