linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oliver Hartkopp <socketcan@hartkopp.net>
To: Marc Kleine-Budde <mkl@pengutronix.de>,
	Oleksij Rempel <o.rempel@pengutronix.de>,
	dev.kurt@vandijck-laurijssen.be, wg@grandegger.com
Cc: netdev@vger.kernel.org, kernel@pengutronix.de, linux-can@vger.kernel.org
Subject: Re: [RFC] can: can_create_echo_skb(): fix echo skb generation: always use skb_clone()
Date: Sat, 17 Oct 2020 21:13:14 +0200	[thread overview]
Message-ID: <f06cd4bc-6264-242f-fd74-ac8e3f2c10b2@hartkopp.net> (raw)
In-Reply-To: <f2ae9b3a-0d10-64ae-1533-2308e9346ebc@pengutronix.de>



On 16.10.20 21:36, Marc Kleine-Budde wrote:
> On 2/14/20 1:09 PM, Oleksij Rempel wrote:
>> Hi all,
>>
>> any comments on this patch?
> 
> I'm going to take this patch now for 5.10....Comments?

Yes.

Removing the sk reference will lead to the effect, that you will receive 
the CAN frames you have sent on that socket - which is disabled by default:

https://elixir.bootlin.com/linux/latest/source/net/can/raw.c#L124

See concept here:

https://elixir.bootlin.com/linux/latest/source/Documentation/networking/can.rst#L560

How can we maintain the CAN_RAW_RECV_OWN_MSGS to be disabled by default 
and fix the described problem?

Regards,
Oliver

> 
> Marc
> 
>>
>> On Fri, Jan 24, 2020 at 02:26:56PM +0100, Oleksij Rempel wrote:
>>> All user space generated SKBs are owned by a socket (unless injected
>>> into the key via AF_PACKET). If a socket is closed, all associated skbs
>>> will be cleaned up.
>>>
>>> This leads to a problem when a CAN driver calls can_put_echo_skb() on a
>>> unshared SKB. If the socket is closed prior to the TX complete handler,
>>> can_get_echo_skb() and the subsequent delivering of the echo SKB to
>>> all registered callbacks, a SKB with a refcount of 0 is delivered.
>>>
>>> To avoid the problem, in can_get_echo_skb() the original SKB is now
>>> always cloned, regardless of shared SKB or not. If the process exists it
>>> can now safely discard its SKBs, without disturbing the delivery of the
>>> echo SKB.
>>>
>>> The problem shows up in the j1939 stack, when it clones the
>>> incoming skb, which detects the already 0 refcount.
>>>
>>> We can easily reproduce this with following example:
>>>
>>> testj1939 -B -r can0: &
>>> cansend can0 1823ff40#0123
>>>
>>> WARNING: CPU: 0 PID: 293 at lib/refcount.c:25 refcount_warn_saturate+0x108/0x174
>>> refcount_t: addition on 0; use-after-free.
>>> Modules linked in: coda_vpu imx_vdoa videobuf2_vmalloc dw_hdmi_ahb_audio vcan
>>> CPU: 0 PID: 293 Comm: cansend Not tainted 5.5.0-rc6-00376-g9e20dcb7040d #1
>>> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
>>> Backtrace:
>>> [<c010f570>] (dump_backtrace) from [<c010f90c>] (show_stack+0x20/0x24)
>>> [<c010f8ec>] (show_stack) from [<c0c3e1a4>] (dump_stack+0x8c/0xa0)
>>> [<c0c3e118>] (dump_stack) from [<c0127fec>] (__warn+0xe0/0x108)
>>> [<c0127f0c>] (__warn) from [<c01283c8>] (warn_slowpath_fmt+0xa8/0xcc)
>>> [<c0128324>] (warn_slowpath_fmt) from [<c0539c0c>] (refcount_warn_saturate+0x108/0x174)
>>> [<c0539b04>] (refcount_warn_saturate) from [<c0ad2cac>] (j1939_can_recv+0x20c/0x210)
>>> [<c0ad2aa0>] (j1939_can_recv) from [<c0ac9dc8>] (can_rcv_filter+0xb4/0x268)
>>> [<c0ac9d14>] (can_rcv_filter) from [<c0aca2cc>] (can_receive+0xb0/0xe4)
>>> [<c0aca21c>] (can_receive) from [<c0aca348>] (can_rcv+0x48/0x98)
>>> [<c0aca300>] (can_rcv) from [<c09b1fdc>] (__netif_receive_skb_one_core+0x64/0x88)
>>> [<c09b1f78>] (__netif_receive_skb_one_core) from [<c09b2070>] (__netif_receive_skb+0x38/0x94)
>>> [<c09b2038>] (__netif_receive_skb) from [<c09b2130>] (netif_receive_skb_internal+0x64/0xf8)
>>> [<c09b20cc>] (netif_receive_skb_internal) from [<c09b21f8>] (netif_receive_skb+0x34/0x19c)
>>> [<c09b21c4>] (netif_receive_skb) from [<c0791278>] (can_rx_offload_napi_poll+0x58/0xb4)
>>>
>>> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
>>> ---
>>>   include/linux/can/skb.h | 20 ++++++++------------
>>>   1 file changed, 8 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
>>> index a954def26c0d..0783b0c6d9e2 100644
>>> --- a/include/linux/can/skb.h
>>> +++ b/include/linux/can/skb.h
>>> @@ -61,21 +61,17 @@ static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
>>>    */
>>>   static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
>>>   {
>>> -	if (skb_shared(skb)) {
>>> -		struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
>>> +	struct sk_buff *nskb;
>>>   
>>> -		if (likely(nskb)) {
>>> -			can_skb_set_owner(nskb, skb->sk);
>>> -			consume_skb(skb);
>>> -			return nskb;
>>> -		} else {
>>> -			kfree_skb(skb);
>>> -			return NULL;
>>> -		}
>>> +	nskb = skb_clone(skb, GFP_ATOMIC);
>>> +	if (unlikely(!nskb)) {
>>> +		kfree_skb(skb);
>>> +		return NULL;
>>>   	}
>>>   
>>> -	/* we can assume to have an unshared skb with proper owner */
>>> -	return skb;
>>> +	can_skb_set_owner(nskb, skb->sk);
>>> +	consume_skb(skb);
>>> +	return nskb;
>>>   }
>>>   
>>>   #endif /* !_CAN_SKB_H */
>>> -- 
>>> 2.25.0
>>>
>>>
>>>
>>
> 
> 

  reply	other threads:[~2020-10-17 19:13 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-24 13:26 [RFC] can: can_create_echo_skb(): fix echo skb generation: always use skb_clone() Oleksij Rempel
2020-02-03 13:43 ` Naresh Kamboju
2020-02-03 13:48   ` Marc Kleine-Budde
2020-02-03 13:52     ` Marc Kleine-Budde
2020-02-03 14:36       ` Naresh Kamboju
2020-02-14 12:09 ` Oleksij Rempel
2020-10-16 19:36   ` Marc Kleine-Budde
2020-10-17 19:13     ` Oliver Hartkopp [this message]
2020-10-18  8:46       ` Oliver Hartkopp
2020-10-19  6:28         ` Marc Kleine-Budde
2020-10-19  6:53           ` Oliver Hartkopp

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=f06cd4bc-6264-242f-fd74-ac8e3f2c10b2@hartkopp.net \
    --to=socketcan@hartkopp.net \
    --cc=dev.kurt@vandijck-laurijssen.be \
    --cc=kernel@pengutronix.de \
    --cc=linux-can@vger.kernel.org \
    --cc=mkl@pengutronix.de \
    --cc=netdev@vger.kernel.org \
    --cc=o.rempel@pengutronix.de \
    --cc=wg@grandegger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).