Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp480736ybl; Tue, 28 Jan 2020 06:37:14 -0800 (PST) X-Google-Smtp-Source: APXvYqxi6be1rgXtxI6Wxk9IMUtEN6tb1cpPUo1SP8ShvGup8cJ0muXHbD4I88aMYrzbWTk2SqgI X-Received: by 2002:aca:d483:: with SMTP id l125mr2908414oig.124.1580222233943; Tue, 28 Jan 2020 06:37:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580222233; cv=none; d=google.com; s=arc-20160816; b=YL0NRkvKf/t0Sigie5L6ee6Hbe7hOQ/oGDUS/MCPEDwf45din5QkpfnxzHuxyXXkQo 6veqH19i/q3Ix+y8EQ/UcRphZJrJklyXPT9qcsSmQ7Qb6DxJC3tS2JRdL8bmJiFNOZVF mz+nXoJeUnLDDToAYX6j4zJbvBDXd9TH0yFgP8EcNsRryytLuzV8LcbyoPboktVUOyTf PfgK2qYvOVAFwyzuykw/bIGhZaoPL/KVHQOknVaHK3ziKNWiixkrsd9Dwdhh7ySVjkvx fxRt+U1bdWUX9Zdc2EP6J5kVv5hUkt9YF00JVJDXPYeTg0iu2utv9duI9Lnh9aBPzVu8 nRJQ== 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=g1xGJVbkuy3QGXxqQj7nKiHjVgG/PQBm+7Oxt1fg51w=; b=Jlc0vJ5mzbC39M2zmLYDm1O8nhyaO+bwCY9ok+DOAsBVrvpNYOtsfZA9OHPEZ3hU7P XcmnTZ23T+7x1j/Wdx+GxqW3Fq5QKwl+CTmzD3AEzTJjf2E1jyNpJvyRX8c5AhoxeBYU +GRT6wv/F/TED0o28dJLtKQalGaP1ree97IyQOhFhW895sLGP5iPEDTQB9TQ4UsxwO7M YmmzFb874WpmQDpzkPVy8UAHFnJZjUdGXun/Rr3VXOfa2en1zqT93TeLuZNHleGNePUZ y5k5RuLkGKW0Yl7CNoceFdk/Y7Es8awIZKWEWPGt2wLXqHwE9FRoVHxoAV8PEut9DPR5 CL1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ZbtC8NHw; 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 v23si8467086otk.321.2020.01.28.06.37.02; Tue, 28 Jan 2020 06:37:13 -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=ZbtC8NHw; 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 S1731298AbgA1OXb (ORCPT + 99 others); Tue, 28 Jan 2020 09:23:31 -0500 Received: from mail.kernel.org ([198.145.29.99]:49608 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732231AbgA1OX3 (ORCPT ); Tue, 28 Jan 2020 09:23:29 -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 C2DF824690; Tue, 28 Jan 2020 14:23:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1580221408; bh=xAXZtDYlOlILeGtjxh9GRlm/T1K2DnWjZ7gl8/6GPJw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZbtC8NHwMLYnZ+8Mtfp2xBGkPIrDozIb4yqBsg9Oku6aOqKm/ygdOV0eTshH3BeWF ir0qZl0pKsuBoKrCbLtYFbtnYmImyIyc9JLJGTUNNWU3AkSYL6HnPpwB0vRfKzOSgw gFl6mv7IeItj6zI1eOy7uZAJMZ8wG0vLIeb41Fyw= 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.9 212/271] llc: fix sk_buff refcounting in llc_conn_state_process() Date: Tue, 28 Jan 2020 15:06:01 +0100 Message-Id: <20200128135908.310315429@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200128135852.449088278@linuxfoundation.org> References: <20200128135852.449088278@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 2689e95471dc4..1bdbd134bd7a8 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