mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-04-13 09:59:31 +00:00
netfilter: nft_exthdr: fix offset with ipv4_find_option()
There is an incorrect calculation in the offset variable which causes
the nft_skb_copy_to_reg() function to always return -EFAULT. Adding the
start variable is redundant. In the __ip_options_compile() function the
correct offset is specified when finding the function. There is no need
to add the size of the iphdr structure to the offset.
Fixes: dbb5281a1f
("netfilter: nf_tables: add support for matching IPv4 options")
Signed-off-by: Alexey Kashavkin <akashavkin@gmail.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
80b78c39eb
commit
6edd78af95
1 changed files with 4 additions and 6 deletions
|
@ -85,7 +85,6 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
|
|||
unsigned char optbuf[sizeof(struct ip_options) + 40];
|
||||
struct ip_options *opt = (struct ip_options *)optbuf;
|
||||
struct iphdr *iph, _iph;
|
||||
unsigned int start;
|
||||
bool found = false;
|
||||
__be32 info;
|
||||
int optlen;
|
||||
|
@ -93,7 +92,6 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
|
|||
iph = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
|
||||
if (!iph)
|
||||
return -EBADMSG;
|
||||
start = sizeof(struct iphdr);
|
||||
|
||||
optlen = iph->ihl * 4 - (int)sizeof(struct iphdr);
|
||||
if (optlen <= 0)
|
||||
|
@ -103,7 +101,7 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
|
|||
/* Copy the options since __ip_options_compile() modifies
|
||||
* the options.
|
||||
*/
|
||||
if (skb_copy_bits(skb, start, opt->__data, optlen))
|
||||
if (skb_copy_bits(skb, sizeof(struct iphdr), opt->__data, optlen))
|
||||
return -EBADMSG;
|
||||
opt->optlen = optlen;
|
||||
|
||||
|
@ -118,18 +116,18 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
|
|||
found = target == IPOPT_SSRR ? opt->is_strictroute :
|
||||
!opt->is_strictroute;
|
||||
if (found)
|
||||
*offset = opt->srr + start;
|
||||
*offset = opt->srr;
|
||||
break;
|
||||
case IPOPT_RR:
|
||||
if (!opt->rr)
|
||||
break;
|
||||
*offset = opt->rr + start;
|
||||
*offset = opt->rr;
|
||||
found = true;
|
||||
break;
|
||||
case IPOPT_RA:
|
||||
if (!opt->router_alert)
|
||||
break;
|
||||
*offset = opt->router_alert + start;
|
||||
*offset = opt->router_alert;
|
||||
found = true;
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue