Received: by 2002:a05:6622:f08:0:0:0:0 with SMTP id l8csp4488554ivc; Tue, 3 Nov 2020 13:22:19 -0800 (PST) X-Google-Smtp-Source: ABdhPJxUhpisrkAPTo1HQ0//zbc+nvIOEaOuR0+1z1pGLj/0RTzQiWzhmVZnTqQzhWdFydP+B/K1 X-Received: by 2002:a50:d615:: with SMTP id x21mr22225303edi.200.1604438538723; Tue, 03 Nov 2020 13:22:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604438538; cv=none; d=google.com; s=arc-20160816; b=TLxFd4UIkzgcFgZsjjEco1JRA3zRA2k8Gbx539pX60o06pdhysbpFODq1cHyOP1Bxm LuyBJ9b0aEBOswMiZ+f8oOUm4rrxiqu6kV1vgholiEjG7qzlRbI0SVIJDUw8bd23XNWk 5bKJ6YYGAnsT7obNM6v9Qdd8OVkqlvOclHCLOV7R+PdfAC3oCkbElclePpJ/r88Ymlas 9VKJULwBfXPuhYSLHXfCZugNZtzr5QjKSByVnyfoUVjE/5fPAbwxbazlFgQbx5CM+YLr 05uZdYSSxVLCsB/y49Bnmzs81uu8rTj37Esxs9Fi0dyMTEwKcAuZ/b5Rqzz6ndG7MoFi 06sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=YBqTJz+ZqPZ95yl7vh/uw+jSoPtjo+s8OKpBXIXEC5o=; b=ux6IDvIyAjScdSD+BdF/k3hZo2LXqujb2YMDyUDHASmkW6tasD+3qu+nu8CIxzfwV1 /eGCFuHQdI7PXlOw3LQfR/BBP2fPJImKjkJSx/2o08ZiSsDCyLG2rk9XwFC4cmtE8g3O tm64Sw1VqvsHiL9VaRa9BIeCE8kAPetAMHG3CNR3cV4kkc29tZyYKy4Vg2DF00oF1fDa dVI3LU4hv3Zzud2hy0Ppw93QOrBtnwai/v/RXTh+5VcRRTWsvuPwVR1h+TwqJwt25s0N gXEG3LaODWlfy+UFrPbskY9BCId+NI1/4yeAkwoTyhqcK8bDzHvCIou9laI0KhI9MDpf Wn3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=07OP5VVz; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o11si16090761edz.483.2020.11.03.13.21.55; Tue, 03 Nov 2020 13:22:18 -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=@kernel.org header.s=default header.b=07OP5VVz; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388742AbgKCVSW (ORCPT + 99 others); Tue, 3 Nov 2020 16:18:22 -0500 Received: from mail.kernel.org ([198.145.29.99]:49424 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388436AbgKCVJY (ORCPT ); Tue, 3 Nov 2020 16:09:24 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id F34C520757; Tue, 3 Nov 2020 21:09:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1604437763; bh=JLcEgLdL/kL4nRVPKC9wWdDIZP3QmaLJDeSXO5Gt35Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=07OP5VVzl6E3dRAWDt+nomVam5Ynr8Ww7aj4/dWkkjNwS3npYukx95HdmHQq/TU5A mpbaNhZ2R5UQdLam+C4QaoAm78ohiEIFvmiFZx8g4oAwFnpPIynphMlMySKN+vcwRu mJAQIECOn86BAz9+jilRoGGqzjrlZ1D6z2AInWWM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jon Maloy , Thang Hoang Ngo , Tung Nguyen , Xin Long , Cong Wang , Jakub Kicinski Subject: [PATCH 4.14 006/125] tipc: fix memory leak caused by tipc_buf_append() Date: Tue, 3 Nov 2020 21:36:23 +0100 Message-Id: <20201103203157.313415426@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201103203156.372184213@linuxfoundation.org> References: <20201103203156.372184213@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tung Nguyen [ Upstream commit ceb1eb2fb609c88363e06618b8d4bbf7815a4e03 ] Commit ed42989eab57 ("tipc: fix the skb_unshare() in tipc_buf_append()") replaced skb_unshare() with skb_copy() to not reduce the data reference counter of the original skb intentionally. This is not the correct way to handle the cloned skb because it causes memory leak in 2 following cases: 1/ Sending multicast messages via broadcast link The original skb list is cloned to the local skb list for local destination. After that, the data reference counter of each skb in the original list has the value of 2. This causes each skb not to be freed after receiving ACK: tipc_link_advance_transmq() { ... /* release skb */ __skb_unlink(skb, &l->transmq); kfree_skb(skb); <-- memory exists after being freed } 2/ Sending multicast messages via replicast link Similar to the above case, each skb cannot be freed after purging the skb list: tipc_mcast_xmit() { ... __skb_queue_purge(pkts); <-- memory exists after being freed } This commit fixes this issue by using skb_unshare() instead. Besides, to avoid use-after-free error reported by KASAN, the pointer to the fragment is set to NULL before calling skb_unshare() to make sure that the original skb is not freed after freeing the fragment 2 times in case skb_unshare() returns NULL. Fixes: ed42989eab57 ("tipc: fix the skb_unshare() in tipc_buf_append()") Acked-by: Jon Maloy Reported-by: Thang Hoang Ngo Signed-off-by: Tung Nguyen Reviewed-by: Xin Long Acked-by: Cong Wang Link: https://lore.kernel.org/r/20201027032403.1823-1-tung.q.nguyen@dektech.com.au Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/tipc/msg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -140,12 +140,11 @@ int tipc_buf_append(struct sk_buff **hea if (fragid == FIRST_FRAGMENT) { if (unlikely(head)) goto err; - if (skb_cloned(frag)) - frag = skb_copy(frag, GFP_ATOMIC); + *buf = NULL; + frag = skb_unshare(frag, GFP_ATOMIC); if (unlikely(!frag)) goto err; head = *headbuf = frag; - *buf = NULL; TIPC_SKB_CB(head)->tail = NULL; if (skb_is_nonlinear(head)) { skb_walk_frags(head, tail) {