Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp455773ybl; Tue, 28 Jan 2020 06:15:33 -0800 (PST) X-Google-Smtp-Source: APXvYqzlXJvbZZPHW8T3HqyLL7OKo51xK2jGcL51dtz1jS/xQqlTF3j/WjHQdaShyEDf9H58qevY X-Received: by 2002:a05:6808:8ca:: with SMTP id k10mr2857075oij.164.1580220933331; Tue, 28 Jan 2020 06:15:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580220933; cv=none; d=google.com; s=arc-20160816; b=nXGuZ8Q6m955v5d8ddDfPQrHyhYgrkRVA7Ji0i/KA52Nqmk4h9LTD0PP0BQoE7WFNN wlJUcOdmreI6BHBkgcun7n/D8LDoPMN5Gu2P+tbB0Z+EPOZlCS6UoknKRVuYn05MSlOB 82MEMjhr9cBo1AsrosXy6/w0bgWVr4Z/hTkTg7JKZ72B3LgO+AvX4J1ybazJ71BDkXxm PwDsC/uHyUSQquxR/Y3hJzz6gs+R5nV9QHgFPK9IMnKA5EkKn2lRAh6wDvv6JmTn/9D/ ibb0bWKASX6UllZfUc3lBuTFL+PJyG6TPAvqrLVwa0bKb3f5yUPMJLvGib9Du4BItVyI /S8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=rJycmEotFDFu3i/CC3xoDvefJA4e4Sqar8Idmwn/cUw=; b=LZSGxHxW5RVSRofdZa6kTS45d8+is1sGfCAiGBX8XC/kfTHJFdW9nwpahLtcGMKWM3 Ft8kUuaKpqG1M/jysRowAR1Qh61MTCSq305ilNkiYE5O2b6JntLNo3swf4QqcOKcAoJH FhiejbARGuaV2aLkAPxz9DrJM6ITiaNXSfQTFOyTWumag8lmUD4/LgF2z1cCKeOkpYRh Sktrp2FOTNIrkzeyWKql2r3w7OufDV1UDoAK1TkthiuZwUf/L6zv5YYG2Tt6zGlZe9/J 7g29YVZGh1HadlDlXX+rJTcDSMpy0iz6sH3OEziFzg4msYK50XgtZUjqHPAGpQ89j5oW l9hw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=K3Aivzzy; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d2si4497385ote.9.2020.01.28.06.15.21; Tue, 28 Jan 2020 06:15:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=K3Aivzzy; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729646AbgA1ONO (ORCPT + 99 others); Tue, 28 Jan 2020 09:13:14 -0500 Received: from mail.kernel.org ([198.145.29.99]:34664 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729624AbgA1ONG (ORCPT ); Tue, 28 Jan 2020 09:13:06 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (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 C405520678; Tue, 28 Jan 2020 14:13:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1580220786; bh=sD5JA99T2jbDhqjq/2YkM6MoGEkyglXfYER3WHOlp9k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K3AivzzyGD98xWT2LKK/njyUC8JmR9+PKIa0+GuMIAtf7z+bUZ3ohqhf5Zmg1c+BZ baCCyuEcEvDk6MB9s+JJbxquKRNbf70+nhUtSDX7eLGUF9nHlvaTddxZvLTaGjZJ+B MucM459zqrtPf4Wn+5nRW3n9JkLFIHG7vctqsmJ4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Biggers , Jakub Kicinski , Sasha Levin Subject: [PATCH 4.4 145/183] llc: fix sk_buff refcounting in llc_conn_state_process() Date: Tue, 28 Jan 2020 15:06:04 +0100 Message-Id: <20200128135844.233791933@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200128135829.486060649@linuxfoundation.org> References: <20200128135829.486060649@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers [ Upstream commit 36453c852816f19947ca482a595dffdd2efa4965 ] If llc_conn_state_process() sees that llc_conn_service() put the skb on a list, it will drop one fewer references to it. This is wrong because the current behavior is that llc_conn_service() never consumes a reference to the skb. The code also makes the number of skb references being dropped conditional on which of ind_prim and cfm_prim are nonzero, yet neither of these affects how many references are *acquired*. So there is extra code that tries to fix this up by sometimes taking another reference. Remove the unnecessary/broken refcounting logic and instead just add an skb_get() before the only two places where an extra reference is actually consumed. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Biggers Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/llc/llc_conn.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 5d653f5261c55..3b002ab68b290 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -64,12 +64,6 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) struct llc_sock *llc = llc_sk(skb->sk); struct llc_conn_state_ev *ev = llc_conn_ev(skb); - /* - * We have to hold the skb, because llc_conn_service will kfree it in - * the sending path and we need to look at the skb->cb, where we encode - * llc_conn_state_ev. - */ - skb_get(skb); ev->ind_prim = ev->cfm_prim = 0; /* * Send event to state machine @@ -77,21 +71,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) rc = llc_conn_service(skb->sk, skb); if (unlikely(rc != 0)) { printk(KERN_ERR "%s: llc_conn_service failed\n", __func__); - goto out_kfree_skb; - } - - if (unlikely(!ev->ind_prim && !ev->cfm_prim)) { - /* indicate or confirm not required */ - if (!skb->next) - goto out_kfree_skb; goto out_skb_put; } - if (unlikely(ev->ind_prim && ev->cfm_prim)) /* Paranoia */ - skb_get(skb); - switch (ev->ind_prim) { case LLC_DATA_PRIM: + skb_get(skb); llc_save_primitive(sk, skb, LLC_DATA_PRIM); if (unlikely(sock_queue_rcv_skb(sk, skb))) { /* @@ -108,6 +93,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) * skb->sk pointing to the newly created struct sock in * llc_conn_handler. -acme */ + skb_get(skb); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_state_change(sk); break; @@ -123,7 +109,6 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) sk->sk_state_change(sk); } } - kfree_skb(skb); sock_put(sk); break; case LLC_RESET_PRIM: @@ -132,14 +117,11 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) * RESET is not being notified to upper layers for now */ printk(KERN_INFO "%s: received a reset ind!\n", __func__); - kfree_skb(skb); break; default: - if (ev->ind_prim) { + if (ev->ind_prim) printk(KERN_INFO "%s: received unknown %d prim!\n", __func__, ev->ind_prim); - kfree_skb(skb); - } /* No indication */ break; } @@ -181,15 +163,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) printk(KERN_INFO "%s: received a reset conf!\n", __func__); break; default: - if (ev->cfm_prim) { + if (ev->cfm_prim) printk(KERN_INFO "%s: received unknown %d prim!\n", __func__, ev->cfm_prim); - break; - } - goto out_skb_put; /* No confirmation */ + /* No confirmation */ + break; } -out_kfree_skb: - kfree_skb(skb); out_skb_put: kfree_skb(skb); return rc; -- 2.20.1