From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933009AbcLPSZw (ORCPT ); Fri, 16 Dec 2016 13:25:52 -0500 Received: from shards.monkeyblade.net ([184.105.139.130]:53368 "EHLO shards.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932775AbcLPSZh (ORCPT ); Fri, 16 Dec 2016 13:25:37 -0500 Date: Fri, 16 Dec 2016 13:25:35 -0500 (EST) Message-Id: <20161216.132535.904601621144551948.davem@davemloft.net> To: tglx@linutronix.de Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, tedheadster@gmail.com, luto@kernel.org Subject: Re: net/3com/3c515: Fix timer handling, prevent leaks and crashes From: David Miller In-Reply-To: References: X-Mailer: Mew version 6.7 on Emacs 25.1 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.5.12 (shards.monkeyblade.net [149.20.54.216]); Fri, 16 Dec 2016 09:26:18 -0800 (PST) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Gleixner Date: Sun, 11 Dec 2016 18:31:22 +0100 (CET) > The timer handling in this driver is broken in several ways: > > - corkscrew_open() initializes and arms a timer before requesting the > device interrupt. If the request fails the timer stays armed. > > A second call to corkscrew_open will unconditionally reinitialize the > quued timer and arm it again. Also a immediate device removal will leave > the timer queued because close() is not called (open() failed) and > therefore nothing issues del_timer(). > > The reinitialization corrupts the link chain in the timer wheel hash > bucket and causes a NULL pointer dereference when the timer wheel tries > to operate on that hash bucket. Immediate device removal lets the link > chain poke into freed and possibly reused memory. > > Solution: Arm the timer after the successful irq request. > > - corkscrew_close() uses del_timer() > > On close the timer is disarmed with del_timer() which lets the following > code race against a concurrent timer expiry function. > > Solution: Use del_timer_sync() instead > > - corkscrew_close() calls del_timer() unconditionally > > del_timer() is invoked even if the timer was never initialized. This > works by chance because the struct containing the timer is zeroed at > allocation time. > > Solution: Move the setup of the timer into corkscrew_setup(). > > Reported-by: Matthew Whitehead > Signed-off-by: Thomas Gleixner Applied, thanks Thomas.