All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: Mohammed Gamal <mgamal@redhat.com>
Cc: otubo@redhat.com, sthemmin@microsoft.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, devel@linuxdriverproject.org,
	vkuznets@redhat.com, davem@davemloft.net
Subject: Re: [PATCH] hv_netvsc: Make sure out channel is fully opened on send
Date: Tue, 13 Mar 2018 12:35:21 -0700	[thread overview]
Message-ID: <20180313123521.5b486da1@xeon-e3> (raw)
In-Reply-To: <1520968010-20733-1-git-send-email-mgamal@redhat.com>

On Tue, 13 Mar 2018 20:06:50 +0100
Mohammed Gamal <mgamal@redhat.com> wrote:

> Dring high network traffic changes to network interface parameters
> such as number of channels or MTU can cause a kernel panic with a NULL
> pointer dereference. This is due to netvsc_device_remove() being
> called and deallocating the channel ring buffers, which can then be
> accessed by netvsc_send_pkt() before they're allocated on calling
> netvsc_device_add()
> 
> The patch fixes this problem by checking the channel state and returning
> ENODEV if not yet opened. We also move the call to hv_ringbuf_avail_percent()
> which may access the uninitialized ring buffer.
> 
> Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
> ---
>  drivers/net/hyperv/netvsc.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
> index 0265d70..44a8358 100644
> --- a/drivers/net/hyperv/netvsc.c
> +++ b/drivers/net/hyperv/netvsc.c
> @@ -757,7 +757,7 @@ static inline int netvsc_send_pkt(
>  	struct netdev_queue *txq = netdev_get_tx_queue(ndev, packet->q_idx);
>  	u64 req_id;
>  	int ret;
> -	u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
> +	u32 ring_avail;
>  
>  	nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
>  	if (skb)
> @@ -773,7 +773,7 @@ static inline int netvsc_send_pkt(
>  
>  	req_id = (ulong)skb;
>  
> -	if (out_channel->rescind)
> +	if (out_channel->rescind || out_channel->state != CHANNEL_OPENED_STATE)
>  		return -ENODEV;
>  
>  	if (packet->page_buf_cnt) {
> @@ -791,6 +791,7 @@ static inline int netvsc_send_pkt(
>  				       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
>  	}
>  
> +	ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
>  	if (ret == 0) {
>  		atomic_inc_return(&nvchan->queue_sends);
>  

Thanks for your patch. Yes there are races with the current update
logic. The root cause goes higher up in the flow; the send queues should
be stopped before netvsc_device_remove is called. Solving it where you tried
to is racy and not going to work reliably.

Network patches should go to netdev@vger.kernel.org

You can't move the ring_avail check until after the vmbus_sendpacket because
that will break the flow control logic.

Instead, you should just move the avail_read check until just after the existing rescind
check.

Also, you shouldn't need to check for OPENED_STATE, just rescind is enough.




_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

WARNING: multiple messages have this Message-ID (diff)
From: Stephen Hemminger <stephen@networkplumber.org>
To: Mohammed Gamal <mgamal@redhat.com>
Cc: netdev@vger.kernel.org, sthemmin@microsoft.com, otubo@redhat.com,
	linux-kernel@vger.kernel.org, devel@linuxdriverproject.org,
	vkuznets@redhat.com, davem@davemloft.net
Subject: Re: [PATCH] hv_netvsc: Make sure out channel is fully opened on send
Date: Tue, 13 Mar 2018 12:35:21 -0700	[thread overview]
Message-ID: <20180313123521.5b486da1@xeon-e3> (raw)
In-Reply-To: <1520968010-20733-1-git-send-email-mgamal@redhat.com>

On Tue, 13 Mar 2018 20:06:50 +0100
Mohammed Gamal <mgamal@redhat.com> wrote:

> Dring high network traffic changes to network interface parameters
> such as number of channels or MTU can cause a kernel panic with a NULL
> pointer dereference. This is due to netvsc_device_remove() being
> called and deallocating the channel ring buffers, which can then be
> accessed by netvsc_send_pkt() before they're allocated on calling
> netvsc_device_add()
> 
> The patch fixes this problem by checking the channel state and returning
> ENODEV if not yet opened. We also move the call to hv_ringbuf_avail_percent()
> which may access the uninitialized ring buffer.
> 
> Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
> ---
>  drivers/net/hyperv/netvsc.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
> index 0265d70..44a8358 100644
> --- a/drivers/net/hyperv/netvsc.c
> +++ b/drivers/net/hyperv/netvsc.c
> @@ -757,7 +757,7 @@ static inline int netvsc_send_pkt(
>  	struct netdev_queue *txq = netdev_get_tx_queue(ndev, packet->q_idx);
>  	u64 req_id;
>  	int ret;
> -	u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
> +	u32 ring_avail;
>  
>  	nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
>  	if (skb)
> @@ -773,7 +773,7 @@ static inline int netvsc_send_pkt(
>  
>  	req_id = (ulong)skb;
>  
> -	if (out_channel->rescind)
> +	if (out_channel->rescind || out_channel->state != CHANNEL_OPENED_STATE)
>  		return -ENODEV;
>  
>  	if (packet->page_buf_cnt) {
> @@ -791,6 +791,7 @@ static inline int netvsc_send_pkt(
>  				       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
>  	}
>  
> +	ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
>  	if (ret == 0) {
>  		atomic_inc_return(&nvchan->queue_sends);
>  

Thanks for your patch. Yes there are races with the current update
logic. The root cause goes higher up in the flow; the send queues should
be stopped before netvsc_device_remove is called. Solving it where you tried
to is racy and not going to work reliably.

Network patches should go to netdev@vger.kernel.org

You can't move the ring_avail check until after the vmbus_sendpacket because
that will break the flow control logic.

Instead, you should just move the avail_read check until just after the existing rescind
check.

Also, you shouldn't need to check for OPENED_STATE, just rescind is enough.

  reply	other threads:[~2018-03-13 19:35 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-13 19:06 [PATCH] hv_netvsc: Make sure out channel is fully opened on send Mohammed Gamal
2018-03-13 19:06 ` Mohammed Gamal
2018-03-13 19:35 ` Stephen Hemminger [this message]
2018-03-13 19:35   ` Stephen Hemminger
2018-03-14  9:22   ` Mohammed Gamal
2018-03-15 16:24     ` Mohammed Gamal
2018-03-15 17:40       ` Stephen Hemminger
2018-03-15 17:40         ` Stephen Hemminger
2018-03-14  8:27 ` Dan Carpenter
2018-03-14  8:27   ` Dan Carpenter
2018-03-16 14:16 ` David Miller
2018-03-16 14:16   ` David Miller
  -- strict thread matches above, loose matches on Subject: below --
2018-09-26 16:34 Mohammed Gamal
2018-09-26 17:13 ` Haiyang Zhang
2018-09-27  8:57   ` Mohammed Gamal
2018-09-27  8:57     ` Mohammed Gamal
2018-09-27 10:23     ` Stephen Hemminger
2018-09-27 10:31       ` Mohammed Gamal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180313123521.5b486da1@xeon-e3 \
    --to=stephen@networkplumber.org \
    --cc=davem@davemloft.net \
    --cc=devel@linuxdriverproject.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgamal@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=otubo@redhat.com \
    --cc=sthemmin@microsoft.com \
    --cc=vkuznets@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.