Skip to content

Commit

Permalink
netfilter: flowtable: validate pppoe header
Browse files Browse the repository at this point in the history
Ensure there is sufficient room to access the protocol field of the
PPPoe header. Validate it once before the flowtable lookup, then use a
helper function to access protocol field.

Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com
Fixes: 72efd58 ("netfilter: flowtable: add pppoe support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
ummakynes committed Apr 11, 2024
1 parent 3cfc9ec commit 87b3593
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
12 changes: 11 additions & 1 deletion include/net/netfilter/nf_flow_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow,
int nf_flow_table_offload_init(void);
void nf_flow_table_offload_exit(void);

static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
{
__be16 proto;

Expand All @@ -352,6 +352,16 @@ static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
return 0;
}

static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
{
if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
return false;

*inner_proto = __nf_flow_pppoe_proto(skb);

return true;
}

#define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count)
#define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count)
#define NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count) \
Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/nf_flow_table_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
proto = veth->h_vlan_encapsulated_proto;
break;
case htons(ETH_P_PPP_SES):
proto = nf_flow_pppoe_proto(skb);
if (!nf_flow_pppoe_proto(skb, &proto))
return NF_ACCEPT;
break;
default:
proto = skb->protocol;
Expand Down
8 changes: 5 additions & 3 deletions net/netfilter/nf_flow_table_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,11 @@ static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
return NF_STOLEN;
}

static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
u32 *offset)
{
struct vlan_ethhdr *veth;
__be16 inner_proto;

switch (skb->protocol) {
case htons(ETH_P_8021Q):
Expand All @@ -287,7 +288,8 @@ static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
}
break;
case htons(ETH_P_PPP_SES):
if (nf_flow_pppoe_proto(skb) == proto) {
if (nf_flow_pppoe_proto(skb, &inner_proto) &&
inner_proto == proto) {
*offset += PPPOE_SES_HLEN;
return true;
}
Expand Down Expand Up @@ -316,7 +318,7 @@ static void nf_flow_encap_pop(struct sk_buff *skb,
skb_reset_network_header(skb);
break;
case htons(ETH_P_PPP_SES):
skb->protocol = nf_flow_pppoe_proto(skb);
skb->protocol = __nf_flow_pppoe_proto(skb);
skb_pull(skb, PPPOE_SES_HLEN);
skb_reset_network_header(skb);
break;
Expand Down

0 comments on commit 87b3593

Please sign in to comment.