hostapd: Fix compile against mbedtsl 3.6
[openwrt/staging/nbd.git] / target / linux / generic / backport-6.6 / 740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch
1 From: Pablo Neira Ayuso <pablo@netfilter.org>
2 Date: Thu, 11 Apr 2024 13:28:59 +0200
3 Subject: [PATCH] netfilter: flowtable: validate pppoe header
4
5 Ensure there is sufficient room to access the protocol field of the
6 PPPoe header. Validate it once before the flowtable lookup, then use a
7 helper function to access protocol field.
8
9 Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com
10 Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support")
11 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
12 ---
13
14 --- a/include/net/netfilter/nf_flow_table.h
15 +++ b/include/net/netfilter/nf_flow_table.h
16 @@ -335,7 +335,7 @@ int nf_flow_rule_route_ipv6(struct net *
17 int nf_flow_table_offload_init(void);
18 void nf_flow_table_offload_exit(void);
19
20 -static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
21 +static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
22 {
23 __be16 proto;
24
25 @@ -351,6 +351,16 @@ static inline __be16 nf_flow_pppoe_proto
26 return 0;
27 }
28
29 +static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
30 +{
31 + if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
32 + return false;
33 +
34 + *inner_proto = __nf_flow_pppoe_proto(skb);
35 +
36 + return true;
37 +}
38 +
39 #define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count)
40 #define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count)
41 #define NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count) \
42 --- a/net/netfilter/nf_flow_table_inet.c
43 +++ b/net/netfilter/nf_flow_table_inet.c
44 @@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, st
45 proto = veth->h_vlan_encapsulated_proto;
46 break;
47 case htons(ETH_P_PPP_SES):
48 - proto = nf_flow_pppoe_proto(skb);
49 + if (!nf_flow_pppoe_proto(skb, &proto))
50 + return NF_ACCEPT;
51 break;
52 default:
53 proto = skb->protocol;
54 --- a/net/netfilter/nf_flow_table_ip.c
55 +++ b/net/netfilter/nf_flow_table_ip.c
56 @@ -273,10 +273,11 @@ static unsigned int nf_flow_xmit_xfrm(st
57 return NF_STOLEN;
58 }
59
60 -static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
61 +static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
62 u32 *offset)
63 {
64 struct vlan_ethhdr *veth;
65 + __be16 inner_proto;
66
67 switch (skb->protocol) {
68 case htons(ETH_P_8021Q):
69 @@ -287,7 +288,8 @@ static bool nf_flow_skb_encap_protocol(c
70 }
71 break;
72 case htons(ETH_P_PPP_SES):
73 - if (nf_flow_pppoe_proto(skb) == proto) {
74 + if (nf_flow_pppoe_proto(skb, &inner_proto) &&
75 + inner_proto == proto) {
76 *offset += PPPOE_SES_HLEN;
77 return true;
78 }
79 @@ -316,7 +318,7 @@ static void nf_flow_encap_pop(struct sk_
80 skb_reset_network_header(skb);
81 break;
82 case htons(ETH_P_PPP_SES):
83 - skb->protocol = nf_flow_pppoe_proto(skb);
84 + skb->protocol = __nf_flow_pppoe_proto(skb);
85 skb_pull(skb, PPPOE_SES_HLEN);
86 skb_reset_network_header(skb);
87 break;