From patchwork Mon Sep 28 09:32:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander 'lynxis' Couzens X-Patchwork-Id: 523286 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A582B1401AF for ; Mon, 28 Sep 2015 20:00:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932269AbbI1KA3 (ORCPT ); Mon, 28 Sep 2015 06:00:29 -0400 Received: from mail.base45.de ([80.241.61.77]:53850 "EHLO mail.base45.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757023AbbI1KA2 (ORCPT ); Mon, 28 Sep 2015 06:00:28 -0400 X-Greylist: delayed 1653 seconds by postgrey-1.27 at vger.kernel.org; Mon, 28 Sep 2015 06:00:28 EDT Received: from [2001:1a80:2258:7f01:209e:40ee:9fdf:db01] (helo=lazus.yip) by mail.base45.de with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA256:128) (Exim 4.82) (envelope-from ) id 1ZgUni-0008Fk-3l; Mon, 28 Sep 2015 11:32:50 +0200 From: Alexander Couzens To: netdev@vger.kernel.org Cc: "David S. Miller" , Alexander Couzens Subject: [PATCH] l2tp: protect tunnel->del_work by ref_count Date: Mon, 28 Sep 2015 11:32:42 +0200 Message-Id: <1443432762-5561-1-git-send-email-lynxis@fe80.eu> X-Mailer: git-send-email 2.5.3 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org There is a small chance that tunnel_free() is called before tunnel->del_work scheduled resulting in a zero pointer dereference. Signed-off-by: Alexander Couzens Acked-by: James Chapman --- net/l2tp/l2tp_core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index f6b090d..afca2eb 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1319,7 +1319,7 @@ static void l2tp_tunnel_del_work(struct work_struct *work) tunnel = container_of(work, struct l2tp_tunnel, del_work); sk = l2tp_tunnel_sock_lookup(tunnel); if (!sk) - return; + goto out; sock = sk->sk_socket; @@ -1341,6 +1341,8 @@ static void l2tp_tunnel_del_work(struct work_struct *work) } l2tp_tunnel_sock_put(sk); +out: + l2tp_tunnel_dec_refcount(tunnel); } /* Create a socket for the tunnel, if one isn't set up by @@ -1636,8 +1638,13 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create); */ int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) { + l2tp_tunnel_inc_refcount(tunnel); l2tp_tunnel_closeall(tunnel); - return (false == queue_work(l2tp_wq, &tunnel->del_work)); + if (false == queue_work(l2tp_wq, &tunnel->del_work)) { + l2tp_tunnel_dec_refcount(tunnel); + return 1; + } + return 0; } EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);