The maximum message size that can be send is bigger than
the  maximum site that skb_page_frag_refill can allocate.
So it is possible to write beyond the allocated buffer.
Fix this by doing a fallback to COW in that case.
v2:
Avoid get get_order() costs as suggested by Linus Torvalds.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
Reported-by: valis <sec@valis.email>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
 
 #include <linux/skbuff.h>
 
+#define ESP_SKB_FRAG_MAXSIZE (PAGE_SIZE << SKB_FRAG_PAGE_ORDER)
+
 struct ip_esp_hdr;
 
 static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
 
        struct page *page;
        struct sk_buff *trailer;
        int tailen = esp->tailen;
+       unsigned int allocsz;
 
        /* this is non-NULL only with TCP/UDP Encapsulation */
        if (x->encap) {
                        return err;
        }
 
+       allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
+       if (allocsz > ESP_SKB_FRAG_MAXSIZE)
+               goto cow;
+
        if (!skb_cloned(skb)) {
                if (tailen <= skb_tailroom(skb)) {
                        nfrags = 1;
 
        struct page *page;
        struct sk_buff *trailer;
        int tailen = esp->tailen;
+       unsigned int allocsz;
 
        if (x->encap) {
                int err = esp6_output_encap(x, skb, esp);
                        return err;
        }
 
+       allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
+       if (allocsz > ESP_SKB_FRAG_MAXSIZE)
+               goto cow;
+
        if (!skb_cloned(skb)) {
                if (tailen <= skb_tailroom(skb)) {
                        nfrags = 1;