[Devel] [PATCH vz8 2/2] tun: Silence allocation failer if user asked for too big header

Konstantin Khorenko khorenko at virtuozzo.com
Tue Jun 15 20:26:51 MSK 2021


According to https://jira.sw.ru/browse/PSBM-103639?focusedCommentId=3000918&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-3000918

it seems the problem is not easily triggerable on RHEL8/ms => let's drop this patch for now.
Until we face the issue again, at least.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 06/12/2021 01:34 AM, Valeriy Vdovin wrote:
> From: Andrey Ryabinin <aryabinin at virtuozzo.com>
>
> 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 <aryabinin at virtuozzo.com>
> (cherry-picked from 1e0ad3477bddaf5621b7cc620e6ed64e405ec8cd)
> https://jira.sw.ru/browse/PSBM-127856
> Signed-off-by: Valeriy Vdovin <valeriy.vdovin at 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 7342c5beeb90..5fc760171a59 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1574,8 +1574,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);
>  	if (!skb)
>  		return ERR_PTR(err);
>
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 2eaadfbf342c..294a8ff3c594 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -1664,6 +1664,13 @@ struct sk_buff *sock_alloc_send_skb_flags(struct sock *sk,
>  struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
>  				     unsigned long data_len, int noblock,
>  				     int *errcode, int max_page_order);
> +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);
>  void *sock_kmalloc(struct sock *sk, int size, gfp_t priority);
>  void sock_kfree_s(struct sock *sk, void *mem, int size);
>  void sock_kzfree_s(struct sock *sk, void *mem, int size);
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 4d60c8473fd9..d04f93ab1691 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -2228,6 +2228,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)
>  {
>


More information about the Devel mailing list