Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp257158pxb; Wed, 24 Feb 2021 00:58:17 -0800 (PST) X-Google-Smtp-Source: ABdhPJw5yDPtJjWxE38AJeqXvpfjk98J24LlhCWvOwvgSuWpyBkoiHiIGXwXbHARipmIHMJDrQUI X-Received: by 2002:a17:906:780b:: with SMTP id u11mr30379066ejm.492.1614157097521; Wed, 24 Feb 2021 00:58:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614157097; cv=none; d=google.com; s=arc-20160816; b=Sf+0ww1fdCwoASXJ4ArSAZAENGqJDSyuT+m6ZJL88o2UqjkV2zrCCdiZh8piuVcE8x sat2Tm72LjmCWZqueILZKzctUudjD7UTjQbLeR95aMFuDisYmtMo0akrQJ0cnZrNwfVG pM9+3lgwrAvJdyVPMvrL7y2kF9wJlWfuBqKdhuCiCg0vhC0021VrziTfFGyrXljHL2GV 7DFLJGUmYiV8YgsCMjbbnQsaOIexk34Kfm979vfhTtTH+3yoSyiIkXUBrIAO/IuflLaF a4dUHDvhyD2jbFhYSz6DkXfd6SzbNX+uWsejyaVaYvvrt9ooQY0MEJLhoNtYGxEbaSaz T4dA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=BGwJ0SHFnCl5BWg2YtrAv0Cs7u3OxCrNO9fhAiDyyc0=; b=NsT242H+YmO6goaQV6iAdLOQxIJw5QXw/Fe/TY1AJ4Alp74xM9wTmKQ3sgOgc6EpF+ X0cQi3AQM3/aGdtUMJzMzyX+FLt+9deVwwszkWFGNIRCpsnUrYtd68GT3KXwnwBRjEII tl5b6ib1zZ7T8rtVzmdIrzJVCXOF21rAy/jYqkB1xVqH2noWPY2XRcY16Op1gTk7O/74 hHEcvigWW1lg8+aTncyx+6n6EhoNHGLk6ErNjfYzoFWlNaPQmWIVr69rDG+YmNHG8a0l +kRVVr8Je5xbwcrywdHUB5w5rtSOjyDO45CMG8kwSG6sbPBKfeFy7bQsDWi2tz7CLGPr ZH7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=sI++S4ET; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t4si10070ejf.475.2021.02.24.00.57.54; Wed, 24 Feb 2021 00:58:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=sI++S4ET; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234660AbhBXIyW (ORCPT + 99 others); Wed, 24 Feb 2021 03:54:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234646AbhBXIx7 (ORCPT ); Wed, 24 Feb 2021 03:53:59 -0500 Received: from mail-yb1-xb2f.google.com (mail-yb1-xb2f.google.com [IPv6:2607:f8b0:4864:20::b2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70128C061574 for ; Wed, 24 Feb 2021 00:53:19 -0800 (PST) Received: by mail-yb1-xb2f.google.com with SMTP id 133so1129383ybd.5 for ; Wed, 24 Feb 2021 00:53:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=BGwJ0SHFnCl5BWg2YtrAv0Cs7u3OxCrNO9fhAiDyyc0=; b=sI++S4ETsAzOHE1Ik9dxQNVCfXfwgtiZoyvMOVvSERvzvyvLkk+1KJTj08NYT8Awrq mDvMPaqTS/XQop0MEqVKk/CI7p690Rp3cdkqt9MZBSpXl2cQ+SQAquMEBI56pMje4cIK sxtQDhChAjn47HWlLgXaQIZSkQ6kCFPcvYTa0fDzCYG8/EWhUlvpPFklNr7W170/0Q11 cc+WIRo6e8Bt3FT8dPbLnheeuMn1CoIgzTanRe/m+CgwzHTWb+cwMLVql27ggg0ux+PL rr/C5JwvZx3DlT7Y2gZkBjFro3xQoJD+W76Muh44QAUCPeKkScIOtHSnmU5RmLNOGwaz rhWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=BGwJ0SHFnCl5BWg2YtrAv0Cs7u3OxCrNO9fhAiDyyc0=; b=YED84I9WPwvpv6ApAtR4Cr30EmCeQjIiv8jkZ1HZKbxjVonVi7kPcOkFLNpPu0xRxn o2gsIi52fmC4RqzhOJ3ggebsGSm7eVznd6J1Ec57msPZ/h9cUMyhFTlOmxt2Ub62AgHl iQjfsOHVWgcOXa5XoqiQdW7hIkvEt3/gMGzE4nMXArU6UgSfzcF4VVz933a2hVmNaobv twROB5zFm8Coq9e4COCgRRHB8A4ac3/wlLIFVPqey1g36vOHGHdcCRS1uI1C2o7pO/1S vMoi9tN3O4XW5TGqrzwSSG9ljX2AQLoiAwb8+4X6ovRoOxI2XkICqQrJbbk2ucNF+cqu uBEQ== X-Gm-Message-State: AOAM531OC0tLbh6aoxc3lAGpCMBbtDd3UntEvhMYr4h0tgi4wkSnEn2M UgEBJjqrEJJO3V1HoPAaLx6Dh70FhZceg8eM/VaV3w== X-Received: by 2002:a25:1d88:: with SMTP id d130mr47638433ybd.446.1614156798239; Wed, 24 Feb 2021 00:53:18 -0800 (PST) MIME-Version: 1.0 References: <20210224075932.20234-1-o.rempel@pengutronix.de> In-Reply-To: <20210224075932.20234-1-o.rempel@pengutronix.de> From: Eric Dumazet Date: Wed, 24 Feb 2021 09:53:06 +0100 Message-ID: Subject: Re: [PATCH net v3 1/1] can: can_skb_set_owner(): fix ref counting if socket was closed before setting skb ownership To: Oleksij Rempel Cc: Marc Kleine-Budde , "David S. Miller" , Jakub Kicinski , Oliver Hartkopp , Robin van der Gracht , Andre Naujoks , kernel@pengutronix.de, linux-can@vger.kernel.org, netdev , LKML Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Feb 24, 2021 at 8:59 AM Oleksij Rempel wrote: > > There are two ref count variables controlling the free()ing of a socket: > - struct sock::sk_refcnt - which is changed by sock_hold()/sock_put() > - struct sock::sk_wmem_alloc - which accounts the memory allocated by > the skbs in the send path. > > In case there are still TX skbs on the fly and the socket() is closed, > the struct sock::sk_refcnt reaches 0. In the TX-path the CAN stack > clones an "echo" skb, calls sock_hold() on the original socket and > references it. This produces the following back trace: > > | WARNING: CPU: 0 PID: 280 at lib/refcount.c:25 refcount_warn_saturate+0x114/0x134 > | refcount_t: addition on 0; use-after-free. > | Modules linked in: coda_vpu(E) v4l2_jpeg(E) videobuf2_vmalloc(E) imx_vdoa(E) > | CPU: 0 PID: 280 Comm: test_can.sh Tainted: G E 5.11.0-04577-gf8ff6603c617 #203 > | Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) > | Backtrace: > | [<80bafea4>] (dump_backtrace) from [<80bb0280>] (show_stack+0x20/0x24) r7:00000000 r6:600f0113 r5:00000000 r4:81441220 > | [<80bb0260>] (show_stack) from [<80bb593c>] (dump_stack+0xa0/0xc8) > | [<80bb589c>] (dump_stack) from [<8012b268>] (__warn+0xd4/0x114) r9:00000019 r8:80f4a8c2 r7:83e4150c r6:00000000 r5:00000009 r4:80528f90 > | [<8012b194>] (__warn) from [<80bb09c4>] (warn_slowpath_fmt+0x88/0xc8) r9:83f26400 r8:80f4a8d1 r7:00000009 r6:80528f90 r5:00000019 r4:80f4a8c2 > | [<80bb0940>] (warn_slowpath_fmt) from [<80528f90>] (refcount_warn_saturate+0x114/0x134) r8:00000000 r7:00000000 r6:82b44000 r5:834e5600 r4:83f4d540 > | [<80528e7c>] (refcount_warn_saturate) from [<8079a4c8>] (__refcount_add.constprop.0+0x4c/0x50) > | [<8079a47c>] (__refcount_add.constprop.0) from [<8079a57c>] (can_put_echo_skb+0xb0/0x13c) > | [<8079a4cc>] (can_put_echo_skb) from [<8079ba98>] (flexcan_start_xmit+0x1c4/0x230) r9:00000010 r8:83f48610 r7:0fdc0000 r6:0c080000 r5:82b44000 r4:834e5600 > | [<8079b8d4>] (flexcan_start_xmit) from [<80969078>] (netdev_start_xmit+0x44/0x70) r9:814c0ba0 r8:80c8790c r7:00000000 r6:834e5600 r5:82b44000 r4:82ab1f00 > | [<80969034>] (netdev_start_xmit) from [<809725a4>] (dev_hard_start_xmit+0x19c/0x318) r9:814c0ba0 r8:00000000 r7:82ab1f00 r6:82b44000 r5:00000000 r4:834e5600 > | [<80972408>] (dev_hard_start_xmit) from [<809c6584>] (sch_direct_xmit+0xcc/0x264) r10:834e5600 r9:00000000 r8:00000000 r7:82b44000 r6:82ab1f00 r5:834e5600 r4:83f27400 > | [<809c64b8>] (sch_direct_xmit) from [<809c6c0c>] (__qdisc_run+0x4f0/0x534) > > To fix this problem, only set skb ownership to sockets which have still > a ref count > 0. > > Cc: Oliver Hartkopp > Cc: Andre Naujoks > Suggested-by: Eric Dumazet > Fixes: 0ae89beb283a ("can: add destructor for self generated skbs") > Signed-off-by: Oleksij Rempel SGTM Reviewed-by: Eric Dumazet > --- > include/linux/can/skb.h | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h > index 685f34cfba20..655f33aa99e3 100644 > --- a/include/linux/can/skb.h > +++ b/include/linux/can/skb.h > @@ -65,8 +65,7 @@ static inline void can_skb_reserve(struct sk_buff *skb) > > static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) > { > - if (sk) { > - sock_hold(sk); > + if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { > skb->destructor = sock_efree; > skb->sk = sk; > } > -- > 2.29.2 >