Skip to content

Commit 53a5b4f

Browse files
committed
xfrm Fix use after free in __xfrm6_udp_encap_rcv.
A recent patch changed xfrm6_udp_encap_rcv to not free the skb itself anymore but fogot the case where xfrm4_udp_encap_rcv is called subsequently. Fix this by moving the call to xfrm4_udp_encap_rcv from __xfrm6_udp_encap_rcv to xfrm6_udp_encap_rcv. Fixes: 221ddb7 ("xfrm: Support GRO for IPv6 ESP in UDP encapsulation") Signed-off-by: Steffen Klassert <[email protected]>
1 parent efedce3 commit 53a5b4f

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

net/ipv4/xfrm4_input.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ static int __xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb, bool pull
159159
/* process ESP */
160160
return 0;
161161
}
162-
EXPORT_SYMBOL(xfrm4_udp_encap_rcv);
163162

164163
/* If it's a keepalive packet, then just eat it.
165164
* If it's an encapsulated packet, then pass it to the
@@ -184,6 +183,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
184183

185184
return ret;
186185
}
186+
EXPORT_SYMBOL(xfrm4_udp_encap_rcv);
187187

188188
struct sk_buff *xfrm4_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
189189
struct sk_buff *skb)
@@ -223,6 +223,7 @@ struct sk_buff *xfrm4_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
223223

224224
return NULL;
225225
}
226+
EXPORT_SYMBOL(xfrm4_gro_udp_encap_rcv);
226227

227228
int xfrm4_rcv(struct sk_buff *skb)
228229
{

net/ipv6/xfrm6_input.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ static int __xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb, bool pull
8080
__be32 *udpdata32;
8181
u16 encap_type;
8282

83-
if (skb->protocol == htons(ETH_P_IP))
84-
return xfrm4_udp_encap_rcv(sk, skb);
85-
8683
encap_type = READ_ONCE(up->encap_type);
8784
/* if this is not encapsulated socket, then just return now */
8885
if (!encap_type)
@@ -169,6 +166,9 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
169166
{
170167
int ret;
171168

169+
if (skb->protocol == htons(ETH_P_IP))
170+
return xfrm4_udp_encap_rcv(sk, skb);
171+
172172
ret = __xfrm6_udp_encap_rcv(sk, skb, true);
173173
if (!ret)
174174
return xfrm6_rcv_encap(skb, IPPROTO_ESP, 0,
@@ -190,6 +190,9 @@ struct sk_buff *xfrm6_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
190190
struct sk_buff *pp = NULL;
191191
int ret;
192192

193+
if (skb->protocol == htons(ETH_P_IP))
194+
return xfrm4_gro_udp_encap_rcv(sk, head, skb);
195+
193196
offset = offset - sizeof(struct udphdr);
194197

195198
if (!pskb_pull(skb, offset))

0 commit comments

Comments
 (0)