Skip to content

Commit 94e3ca2

Browse files
committed
Merge tag 'ipsec-2024-03-19' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2024-03-19 1) Fix possible page_pool leak triggered by esp_output. From Dragos Tatulea. 2) Fix UDP encapsulation in software GSO path. From Leon Romanovsky. * tag 'ipsec-2024-03-19' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec: xfrm: Allow UDP encapsulation only in offload modes net: esp: fix bad handling of pages from page_pool ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 78a2f5e + 773bb76 commit 94e3ca2

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

include/linux/skbuff.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3523,6 +3523,16 @@ int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb,
35233523
struct bpf_prog *prog);
35243524
bool napi_pp_put_page(struct page *page, bool napi_safe);
35253525

3526+
static inline void
3527+
skb_page_unref(const struct sk_buff *skb, struct page *page, bool napi_safe)
3528+
{
3529+
#ifdef CONFIG_PAGE_POOL
3530+
if (skb->pp_recycle && napi_pp_put_page(page, napi_safe))
3531+
return;
3532+
#endif
3533+
put_page(page);
3534+
}
3535+
35263536
static inline void
35273537
napi_frag_unref(skb_frag_t *frag, bool recycle, bool napi_safe)
35283538
{

net/ipv4/esp4.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
9595
__alignof__(struct scatterlist));
9696
}
9797

98-
static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
98+
static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
9999
{
100100
struct crypto_aead *aead = x->data;
101101
int extralen = 0;
@@ -114,7 +114,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
114114
*/
115115
if (req->src != req->dst)
116116
for (sg = sg_next(req->src); sg; sg = sg_next(sg))
117-
put_page(sg_page(sg));
117+
skb_page_unref(skb, sg_page(sg), false);
118118
}
119119

120120
#ifdef CONFIG_INET_ESPINTCP
@@ -260,7 +260,7 @@ static void esp_output_done(void *data, int err)
260260
}
261261

262262
tmp = ESP_SKB_CB(skb)->tmp;
263-
esp_ssg_unref(x, tmp);
263+
esp_ssg_unref(x, tmp, skb);
264264
kfree(tmp);
265265

266266
if (xo && (xo->flags & XFRM_DEV_RESUME)) {
@@ -639,7 +639,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
639639
}
640640

641641
if (sg != dsg)
642-
esp_ssg_unref(x, tmp);
642+
esp_ssg_unref(x, tmp, skb);
643643

644644
if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
645645
err = esp_output_tail_tcp(x, skb);

net/ipv6/esp6.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
112112
__alignof__(struct scatterlist));
113113
}
114114

115-
static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
115+
static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
116116
{
117117
struct crypto_aead *aead = x->data;
118118
int extralen = 0;
@@ -131,7 +131,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
131131
*/
132132
if (req->src != req->dst)
133133
for (sg = sg_next(req->src); sg; sg = sg_next(sg))
134-
put_page(sg_page(sg));
134+
skb_page_unref(skb, sg_page(sg), false);
135135
}
136136

137137
#ifdef CONFIG_INET6_ESPINTCP
@@ -294,7 +294,7 @@ static void esp_output_done(void *data, int err)
294294
}
295295

296296
tmp = ESP_SKB_CB(skb)->tmp;
297-
esp_ssg_unref(x, tmp);
297+
esp_ssg_unref(x, tmp, skb);
298298
kfree(tmp);
299299

300300
esp_output_encap_csum(skb);
@@ -677,7 +677,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
677677
}
678678

679679
if (sg != dsg)
680-
esp_ssg_unref(x, tmp);
680+
esp_ssg_unref(x, tmp, skb);
681681

682682
if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
683683
err = esp_output_tail_tcp(x, skb);

net/xfrm/xfrm_device.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
407407
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
408408
struct net_device *dev = x->xso.dev;
409409

410-
if (!x->type_offload)
410+
if (!x->type_offload ||
411+
(x->xso.type == XFRM_DEV_OFFLOAD_UNSPECIFIED && x->encap))
411412
return false;
412413

413414
if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET ||

0 commit comments

Comments
 (0)