Received: by 2002:a25:ef43:0:0:0:0:0 with SMTP id w3csp107710ybm; Tue, 26 May 2020 11:59:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzqRMPc1l/eBGoURt7s+KwZVOZ0ugnNfZPpOLiPKtNCXrEkXziyu+W+ne5fc3lhK2uiV4jO X-Received: by 2002:a50:8e56:: with SMTP id 22mr20350652edx.268.1590519590566; Tue, 26 May 2020 11:59:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590519590; cv=none; d=google.com; s=arc-20160816; b=F2hqKuJjXiL06jfR/4AaIxx5avBTx/2qaknyPpdks7BLYRBbMzhaDo3V6+a8d4KXWV tUdvR0jTwPozcyysH0AoudnpXrYYxNQglSEyYPV1YAKmXteQZcDHfoJM9mTz5qC377pC 3JyZRXqKrAGysYz75rtDSsz2r2VZsqq0q7iGQj5ROEnT+41z07OJbEkMeSsj796JWCtz NG1a7JHGzxB0+KXuwYBRsGcQR1F8LcAUp0ZXQqIiewUeK5h4EtZvt8dwCnV+wcMEnOvF CTppQeeHJEqhPuiJVwp1B0jq7EShlu8SD9uYp6tg1I8bG0PztEc5el37JO6yL3Z4VpXl AOuQ== 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=OF0hJjQ0/pSzDIfDvBzJropSmm5pLBwfO3820zEie9I=; b=P9HV9AjjiUAcYCPi247vihompPHKzAtmIGMihbSKZQ7Rd3p1PH78bczCYGDJWghh8w 5AbEC0j8FIAmodCA9um0hhH3TDGLicfaBq2R1LZpITZWVLTbihM2kVWZ0l1CHQh+x+SU 5DBmUuiz9vYMCQntx8zh+AeYTQaK4imYjSKAoJHrMGowcHS981OEZJxvcvAzV5fq2oj9 IF+1n7cmcgROc2LjXdtTG5kYRaDyC02TVPVTIOpH7RVpkSkzrQtQSGSh5BuJzJEOAkyx tkN15m1RLEjeIGvNq/v74EI7fG0MjYJCxaoyC/F5iylIHSDrQX42DAHaC/H/z//D44ME 39GQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="xzJHu0g/"; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s10si422162ejq.400.2020.05.26.11.59.27; Tue, 26 May 2020 11:59:50 -0700 (PDT) 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="xzJHu0g/"; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389956AbgEZS4u (ORCPT + 99 others); Tue, 26 May 2020 14:56:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:49732 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389927AbgEZS4q (ORCPT ); Tue, 26 May 2020 14:56:46 -0400 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 1B1602084C; Tue, 26 May 2020 18:56:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1590519405; bh=P8L8V9kERrS6UiZtfTibSWslJtYHRXsz+aKGZ9SSlaA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xzJHu0g/4d6s95lhm68nUm2tRmwK9SrCd9aaKDjyGYmVp4kfW06gXiy75dx0CEYuu uDBPdwBn0jjbw4wBkEzCyz5acj0f6pk2MkVikjQeySgKUjhEONxYrXmjk6bsEPz+y1 QiY0MQpnajBtHQfHnfEmQQuRhM5lTMtZhwt1X7+4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, greg@kroah.com Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Guillaume Nault , "David S. Miller" , Giuliano Procida Subject: [PATCH 4.4 57/65] l2tp: dont register sessions in l2tp_session_create() Date: Tue, 26 May 2020 20:53:16 +0200 Message-Id: <20200526183927.129928626@linuxfoundation.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526183905.988782958@linuxfoundation.org> References: <20200526183905.988782958@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: Guillaume Nault commit 3953ae7b218df4d1e544b98a393666f9ae58a78c upstream. Sessions created by l2tp_session_create() aren't fully initialised: some pseudo-wire specific operations need to be done before making the session usable. Therefore the PPP and Ethernet pseudo-wires continue working on the returned l2tp session while it's already been exposed to the rest of the system. This can lead to various issues. In particular, the session may enter the deletion process before having been fully initialised, which will confuse the session removal code. This patch moves session registration out of l2tp_session_create(), so that callers can control when the session is exposed to the rest of the system. This is done by the new l2tp_session_register() function. Only pppol2tp_session_create() can be easily converted to avoid modifying its session after registration (the debug message is dropped in order to avoid the need for holding a reference on the session). For pppol2tp_connect() and l2tp_eth_create()), more work is needed. That'll be done in followup patches. For now, let's just register the session right after its creation, like it was done before. The only difference is that we can easily take a reference on the session before registering it, so, at least, we're sure it's not going to be freed while we're working on it. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 21 +++++++-------------- net/l2tp/l2tp_core.h | 3 +++ net/l2tp/l2tp_eth.c | 9 +++++++++ net/l2tp/l2tp_ppp.c | 27 +++++++++++++++++++-------- 4 files changed, 38 insertions(+), 22 deletions(-) --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -321,8 +321,8 @@ struct l2tp_session *l2tp_session_get_by } EXPORT_SYMBOL_GPL(l2tp_session_get_by_ifname); -static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, - struct l2tp_session *session) +int l2tp_session_register(struct l2tp_session *session, + struct l2tp_tunnel *tunnel) { struct l2tp_session *session_walk; struct hlist_head *g_head; @@ -370,6 +370,10 @@ static int l2tp_session_add_to_tunnel(st hlist_add_head(&session->hlist, head); write_unlock_bh(&tunnel->hlist_lock); + /* Ignore management session in session count value */ + if (session->session_id != 0) + atomic_inc(&l2tp_session_count); + return 0; err_tlock_pnlock: @@ -379,6 +383,7 @@ err_tlock: return err; } +EXPORT_SYMBOL_GPL(l2tp_session_register); /* Lookup a tunnel by id */ @@ -1793,7 +1798,6 @@ EXPORT_SYMBOL_GPL(l2tp_session_set_heade struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct l2tp_session *session; - int err; session = kzalloc(sizeof(struct l2tp_session) + priv_size, GFP_KERNEL); if (session != NULL) { @@ -1851,17 +1855,6 @@ struct l2tp_session *l2tp_session_create l2tp_session_inc_refcount(session); - err = l2tp_session_add_to_tunnel(tunnel, session); - if (err) { - kfree(session); - - return ERR_PTR(err); - } - - /* Ignore management session in session count value */ - if (session->session_id != 0) - atomic_inc(&l2tp_session_count); - return session; } --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -262,6 +262,9 @@ struct l2tp_session *l2tp_session_create struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); +int l2tp_session_register(struct l2tp_session *session, + struct l2tp_tunnel *tunnel); + void __l2tp_session_unhash(struct l2tp_session *session); int l2tp_session_delete(struct l2tp_session *session); void l2tp_session_free(struct l2tp_session *session); --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -267,6 +267,13 @@ static int l2tp_eth_create(struct net *n goto out; } + l2tp_session_inc_refcount(session); + rc = l2tp_session_register(session, tunnel); + if (rc < 0) { + kfree(session); + goto out; + } + dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN, l2tp_eth_dev_setup); if (!dev) { @@ -298,6 +305,7 @@ static int l2tp_eth_create(struct net *n __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); + l2tp_session_dec_refcount(session); dev_hold(dev); @@ -308,6 +316,7 @@ out_del_dev: spriv->dev = NULL; out_del_session: l2tp_session_delete(session); + l2tp_session_dec_refcount(session); out: return rc; } --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -737,6 +737,14 @@ static int pppol2tp_connect(struct socke error = PTR_ERR(session); goto end; } + + l2tp_session_inc_refcount(session); + error = l2tp_session_register(session, tunnel); + if (error < 0) { + kfree(session); + goto end; + } + drop_refcnt = true; } /* Associate session with its PPPoL2TP socket */ @@ -822,7 +830,7 @@ static int pppol2tp_session_create(struc /* Error if tunnel socket is not prepped */ if (!tunnel->sock) { error = -ENOENT; - goto out; + goto err; } /* Default MTU values. */ @@ -837,18 +845,21 @@ static int pppol2tp_session_create(struc peer_session_id, cfg); if (IS_ERR(session)) { error = PTR_ERR(session); - goto out; + goto err; } ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock; - l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", - session->name); - - error = 0; - -out: + error = l2tp_session_register(session, tunnel); + if (error < 0) + goto err_sess; + + return 0; + +err_sess: + kfree(session); +err: return error; }