Re: [PATCH] netfilter: nft_exthdr: fix offset with ipv4_find_option()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Rules such as the following will always result in the NFT_BREAK verdict code:
> 
> # filter input ip option rr ptr 4 counter
> 
> Because the function nft_skb_copy_to_reg() returns -EFAULT. This happens because in the skb_copy_bits() function the 'offset > (int)skb->len - len' condition causes a jump to the fault part of the code.
> 

As confirmation, here is a listing from kgdb. Target is Fedora 41 with kernel - 6.11.4-301.fc41.x86_64.

Thread 2 hit Breakpoint 1, nft_exthdr_ipv4_eval (expr=0xffff888004dc1210, regs=0xffffc900001009a0, pkt=0xffffc90000100ab0) at net/netfilter/nft_exthdr.c:163
163		if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0)
(gdb) p offset
$4 = 42
(gdb) n
167		regs->verdict.code = NFT_BREAK;
(gdb) p $eax
$5 = -14
(gdb) c
Continuing.
[Switching to Thread 27]

Thread 25 hit Breakpoint 1, nft_exthdr_ipv4_eval (expr=0xffff888004dc1210, regs=0xffffc900000eb890, pkt=0xffffc900000eb9a0) at net/netfilter/nft_exthdr.c:163
163		if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0)
(gdb) s
nft_skb_copy_to_reg (skb=0xffff888009407f00, offset=42, dest=0xffffc900000eb8a0, len=1) at net/netfilter/nft_exthdr.c:40
40		if (len % NFT_REG32_SIZE)
(gdb) set offset -= sizeof(struct iphdr)
(gdb) p offset
$3 = 22
(gdb) n
41			dest[len / NFT_REG32_SIZE] = 0;
(gdb)
43		return skb_copy_bits(skb, offset, dest, len);
(gdb)
nft_do_chain (pkt=0xffffc900000eb9a0, priv=0x0 <fixed_percpu_data>) at net/netfilter/nf_tables_core.c:290
290				if (regs.verdict.code != NFT_CONTINUE)


With the second packet I manually changed the offset value in nft_skb_copy_to_reg() and, as you can see, the jump to err for the resulting NFT_BREAK did not happen.




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux