mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-01 08:04:22 +08:00
5bd8baab08
Commitebe48d368e
("esp: Fix possible buffer overflow in ESP transformation") tried to fix skb_page_frag_refill usage in ESP by capping allocsize to 32k, but that doesn't completely solve the issue, as skb_page_frag_refill may return a single page. If that happens, we will write out of bounds, despite the check introduced in the previous patch. This patch forces COW in cases where we would end up calling skb_page_frag_refill with a size larger than a page (first in esp_output_head with tailen, then in esp_output_tail with skb->data_len). Fixes:cac2661c53
("esp4: Avoid skb_cow_data whenever possible") Fixes:03e2a30f6a
("esp6: Avoid skb_cow_data whenever possible") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
50 lines
1.2 KiB
C
50 lines
1.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _NET_ESP_H
|
|
#define _NET_ESP_H
|
|
|
|
#include <linux/skbuff.h>
|
|
|
|
struct ip_esp_hdr;
|
|
|
|
static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
|
|
{
|
|
return (struct ip_esp_hdr *)skb_transport_header(skb);
|
|
}
|
|
|
|
static inline void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
|
|
{
|
|
/* Fill padding... */
|
|
if (tfclen) {
|
|
memset(tail, 0, tfclen);
|
|
tail += tfclen;
|
|
}
|
|
do {
|
|
int i;
|
|
for (i = 0; i < plen - 2; i++)
|
|
tail[i] = i + 1;
|
|
} while (0);
|
|
tail[plen - 2] = plen - 2;
|
|
tail[plen - 1] = proto;
|
|
}
|
|
|
|
struct esp_info {
|
|
struct ip_esp_hdr *esph;
|
|
__be64 seqno;
|
|
int tfclen;
|
|
int tailen;
|
|
int plen;
|
|
int clen;
|
|
int len;
|
|
int nfrags;
|
|
__u8 proto;
|
|
bool inplace;
|
|
};
|
|
|
|
int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp);
|
|
int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp);
|
|
int esp_input_done2(struct sk_buff *skb, int err);
|
|
int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp);
|
|
int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp);
|
|
int esp6_input_done2(struct sk_buff *skb, int err);
|
|
#endif
|