On 10/05/2020 04:42 PM, Andrey Ryabinin wrote:
Userspace may ask tun device to send packet with ridiculously
big header and trigger this:
------------[ cut here ]------------
WARNING: CPU: 1 PID: 15366 at mm/page_alloc.c:3548
__alloc_pages_nodemask+0x537/0x1200
order 19 >= 11, gfp 0x2044d0
Call Trace:
dump_stack+0x19/0x1b
__warn+0x17f/0x1c0
warn_slowpath_fmt+0xad/0xe0
__alloc_pages_nodemask+0x537/0x1200
kmalloc_large_node+0x5f/0xd0
__kmalloc_node_track_caller+0x425/0x630
__kmalloc_reserve.isra.33+0x47/0xd0
__alloc_skb+0xdd/0x5f0
alloc_skb_with_frags+0x8f/0x540
sock_alloc_send_pskb+0x5e5/0x940
tun_get_user+0x38b/0x24a0 [tun]
tun_chr_aio_write+0x13a/0x250 [tun]
do_sync_readv_writev+0xdf/0x1c0
do_readv_writev+0x1a5/0x850
vfs_writev+0xba/0x190
SyS_writev+0x17c/0x340
system_call_fastpath+0x25/0x2a
Just add __GFP_NOWARN and silently return -ENOMEM to fix this.
https://jira.sw.ru/browse/PSBM-103639
Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
---
drivers/net/tun.c | 4 ++--
include/net/sock.h | 7 +++++++
net/core/sock.c | 9 +++++++++
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e95a89ba48b7..c0879c6a9703 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1142,8 +1142,8 @@ static struct sk_buff *tun_alloc_skb(struct tun_file
*tfile,
if (prepad + len < PAGE_SIZE || !linear)
linear = len;
- skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
- &err, 0);
+ skb = sock_alloc_send_pskb_flags(sk, prepad + linear, len - linear,
noblock,
+ &err, 0, __GFP_NOWARN);
May be __GFP_ORDER_NOWARN ?
if (!skb)
return ERR_PTR(err);
diff --git a/include/net/sock.h b/include/net/sock.h
index 4136d2c3080c..1912d85ecc4d 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1626,6 +1626,13 @@ extern struct sk_buff
*sock_alloc_send_pskb(struct sock *sk,
int noblock,
int *errcode,
int max_page_order);
+extern struct sk_buff *sock_alloc_send_pskb_flags(struct sock *sk,
+ unsigned long header_len,
+ unsigned long data_len,
+ int noblock,
+ int *errcode,
+ int max_page_order,
+ gfp_t extra_flags);
extern void *sock_kmalloc(struct sock *sk, int size,
gfp_t priority);
extern void sock_kfree_s(struct sock *sk, void *mem, int size);
diff --git a/net/core/sock.c b/net/core/sock.c
index 508fc6093a26..07ea42f976cf 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1964,6 +1964,15 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
unsigned long header_len,
}
EXPORT_SYMBOL(sock_alloc_send_pskb);
+struct sk_buff *sock_alloc_send_pskb_flags(struct sock *sk, unsigned long
header_len,
+ unsigned long data_len, int noblock,
+ int *errcode, int max_page_order, gfp_t
extra_flags)
+{
+ return __sock_alloc_send_pskb(sk, header_len, data_len, noblock,
+ errcode, max_page_order, extra_flags);
+}
+EXPORT_SYMBOL(sock_alloc_send_pskb_flags);
+
struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
int noblock, int *errcode)
{
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel