Skip to content

Commit d1c86e1

Browse files
CIQ Kernel Automationroxanan1996
authored andcommitted
netfilter: flowtable: validate pppoe header
jira VULN-37637 cve CVE-2024-27016 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit 87b3593 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> (cherry picked from commit 87b3593) Signed-off-by: CIQ Kernel Automation <ciq_kernel_automation@ciq.com>
1 parent a9e34de commit d1c86e1

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

include/net/netfilter/nf_flow_table.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
322322
int nf_flow_table_offload_init(void);
323323
void nf_flow_table_offload_exit(void);
324324

325-
static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
325+
static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
326326
{
327327
__be16 proto;
328328

@@ -338,6 +338,16 @@ static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
338338
return 0;
339339
}
340340

341+
static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
342+
{
343+
if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
344+
return false;
345+
346+
*inner_proto = __nf_flow_pppoe_proto(skb);
347+
348+
return true;
349+
}
350+
341351
#define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count)
342352
#define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count)
343353
#define NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count) \

net/netfilter/nf_flow_table_inet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
2121
proto = veth->h_vlan_encapsulated_proto;
2222
break;
2323
case htons(ETH_P_PPP_SES):
24-
proto = nf_flow_pppoe_proto(skb);
24+
if (!nf_flow_pppoe_proto(skb, &proto))
25+
return NF_ACCEPT;
2526
break;
2627
default:
2728
proto = skb->protocol;

net/netfilter/nf_flow_table_ip.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,11 @@ static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
246246
return NF_STOLEN;
247247
}
248248

249-
static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
249+
static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
250250
u32 *offset)
251251
{
252252
struct vlan_ethhdr *veth;
253+
__be16 inner_proto;
253254

254255
switch (skb->protocol) {
255256
case htons(ETH_P_8021Q):
@@ -260,7 +261,8 @@ static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
260261
}
261262
break;
262263
case htons(ETH_P_PPP_SES):
263-
if (nf_flow_pppoe_proto(skb) == proto) {
264+
if (nf_flow_pppoe_proto(skb, &inner_proto) &&
265+
inner_proto == proto) {
264266
*offset += PPPOE_SES_HLEN;
265267
return true;
266268
}
@@ -289,7 +291,7 @@ static void nf_flow_encap_pop(struct sk_buff *skb,
289291
skb_reset_network_header(skb);
290292
break;
291293
case htons(ETH_P_PPP_SES):
292-
skb->protocol = nf_flow_pppoe_proto(skb);
294+
skb->protocol = __nf_flow_pppoe_proto(skb);
293295
skb_pull(skb, PPPOE_SES_HLEN);
294296
skb_reset_network_header(skb);
295297
break;

0 commit comments

Comments
 (0)