Skip to content

Commit e5a37bc

Browse files
committed
netfilter: flowtable: validate pppoe header
jira LE-1907 cve CVE-2024-27016 Rebuild_History Non-Buildable kernel-5.14.0-427.33.1.el9_4 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: Jonathan Maple <jmaple@ciq.com>
1 parent 9e03dd2 commit e5a37bc

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

include/net/netfilter/nf_flow_table.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow,
335335
int nf_flow_table_offload_init(void);
336336
void nf_flow_table_offload_exit(void);
337337

338-
static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
338+
static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
339339
{
340340
__be16 proto;
341341

@@ -351,6 +351,16 @@ static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
351351
return 0;
352352
}
353353

354+
static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
355+
{
356+
if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
357+
return false;
358+
359+
*inner_proto = __nf_flow_pppoe_proto(skb);
360+
361+
return true;
362+
}
363+
354364
#define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count)
355365
#define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count)
356366
#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
@@ -247,10 +247,11 @@ static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
247247
return NF_STOLEN;
248248
}
249249

250-
static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
250+
static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
251251
u32 *offset)
252252
{
253253
struct vlan_ethhdr *veth;
254+
__be16 inner_proto;
254255

255256
switch (skb->protocol) {
256257
case htons(ETH_P_8021Q):
@@ -261,7 +262,8 @@ static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
261262
}
262263
break;
263264
case htons(ETH_P_PPP_SES):
264-
if (nf_flow_pppoe_proto(skb) == proto) {
265+
if (nf_flow_pppoe_proto(skb, &inner_proto) &&
266+
inner_proto == proto) {
265267
*offset += PPPOE_SES_HLEN;
266268
return true;
267269
}
@@ -290,7 +292,7 @@ static void nf_flow_encap_pop(struct sk_buff *skb,
290292
skb_reset_network_header(skb);
291293
break;
292294
case htons(ETH_P_PPP_SES):
293-
skb->protocol = nf_flow_pppoe_proto(skb);
295+
skb->protocol = __nf_flow_pppoe_proto(skb);
294296
skb_pull(skb, PPPOE_SES_HLEN);
295297
skb_reset_network_header(skb);
296298
break;

0 commit comments

Comments
 (0)