Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp2879444ybc; Wed, 20 Nov 2019 23:09:42 -0800 (PST) X-Google-Smtp-Source: APXvYqwzakHzIiNyBmir4+aqnWzPMIrRP/XCPz2DBfksvliI8g3RBgRWeXdNLP9nKSjqJofkAlUT X-Received: by 2002:a17:906:d9c4:: with SMTP id qk4mr11291289ejb.214.1574320182132; Wed, 20 Nov 2019 23:09:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574320182; cv=none; d=google.com; s=arc-20160816; b=I7Pk3OBiknEaN0MCxm9nhQJ7m51yVCZK/2jGYU4rbEdWS2g4RPoNiSfa8zKhM2NFnM 6tCbVpXRyH6DzY5TtKg9tTGYc1WpA0TUIp1BvzSLa+pwnkDAHv4szzj3OVS1zsVwrAwe l9XrP4c/cEFhi2RJcGKOWP0QhC1KbtSOkdqEDQawLznWc27kEJfCL6Kv3L5DADa5MHUj LreO2bit/gBHq9svzxANt95UBCo6NRao7mgPpV3nYSvAMVFgYBZz35Q+Tn38fDwXERUF 6njNiEexI+5EU2DQ4p3IKUpLivjToYLbLrgogHtVcHL09rXwqVpuECBwHgms7GgtjJgf f3jw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=7814KwDvAa7duye/jn+6Qf6QLTHwr2ND+KcdY9LhmGY=; b=az3Guxc7hgZYXZ41qHWbLSWAIn0Unn36qdSaudP1e5OasxMxMJOnwoPrsCk1ySZLpb vlHTom+12+CESH9fE0tofjPmYnSO+Urbwf8ehUQfdJV6cdh59dbFfqJGxJIAXmCddac5 MS8MnsPzWRCOQ2aABQotr7MiH8M78zBNk598rXkS2uKbWMLdFlR8sJqkKcB8rd+3yKfR LbUt+IPAzOIwYhP0qNN7dtQfwmPDXBudo6gqOjFueeBG0E3PXWuGYDLC2LtUGDiBZb9o loGZfqXbQpqrltisYbb+IXn9FE7FsfIzIOzhs41qgocqWRddmQOprymsFXvUx398atrk 5H8Q== ARC-Authentication-Results: i=1; mx.google.com; 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 me8si1129352ejb.382.2019.11.20.23.09.15; Wed, 20 Nov 2019 23:09:42 -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; 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 S1726362AbfKUHII (ORCPT + 99 others); Thu, 21 Nov 2019 02:08:08 -0500 Received: from isilmar-4.linta.de ([136.243.71.142]:50070 "EHLO isilmar-4.linta.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726014AbfKUHII (ORCPT ); Thu, 21 Nov 2019 02:08:08 -0500 X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES Received: from light.dominikbrodowski.net (brodo.linta [10.1.0.102]) by isilmar-4.linta.de (Postfix) with ESMTPSA id 0C9B9200AA9; Thu, 21 Nov 2019 07:08:06 +0000 (UTC) Received: by light.dominikbrodowski.net (Postfix, from userid 1000) id A7639200A0; Thu, 21 Nov 2019 08:07:32 +0100 (CET) Date: Thu, 21 Nov 2019 08:07:32 +0100 From: Dominik Brodowski To: Jia-Ju Bai Cc: Greg KH , arnd@arndb.de, viro@zeniv.linux.org.uk, Linux Kernel Mailing List Subject: Re: [BUG] char: pcmcia: a possible concurrency double-free bug in rx_alloc_buffers() Message-ID: <20191121070732.GA126007@light.dominikbrodowski.net> References: <76309f04-b1e1-11d3-b77f-962bf50c5be2@gmail.com> <20190107085724.GC26384@kroah.com> <1a20e64b-7e2f-9ea1-657d-b0b997092738@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1a20e64b-7e2f-9ea1-657d-b0b997092738@gmail.com> User-Agent: Mutt/1.12.2 (2019-09-21) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jan 07, 2019 at 05:33:43PM +0800, Jia-Ju Bai wrote: > > > On 2019/1/7 16:57, Greg KH wrote: > > On Mon, Jan 07, 2019 at 04:12:22PM +0800, Jia-Ju Bai wrote: > > > In drivers/char/pcmcia/synclink_cs.c, the functions mgslpc_open() and hdlcdev_open() can be concurrently executed. > > > > > > hdlcdev_open > > > startup > > > claim_resources > > > rx_alloc_buffers > > > line 2641: kfree(info->rx_buf) > > > > > > mgslpc_open > > > startup > > > claim_resources > > > rx_alloc_buffers > > > line 2641: kfree(info->rx_buf) > > > > > > Thus, a possible concurrency double-free bug may occur. > > Wait, are you sure those really are the same structure, and that those > > two functions can be called at the same time? That is a tty and a > > network device, are they both created at the same time or does opening > > one create the other? > > hdlcdev_open() is assigned to "hdlcdev_ops.ndo_open". > mgslpc_open() is assigned to "mgslpc_ops.open". > They are indeed assigned to the fields in different data structures. > > **** For hdlcdev_open() **** > In hdlcdev_init(): > dev->netdev_ops = &hdlcdev_ops; > rc = register_hdlc_device(dev); > Thus, hdlcdev_open() can be called after "register_hdlc_device(dev)". > > hdlcdev_init() is called by mgslpc_add_device(), which is called by > mgslpc_probe(). > mgslpc_probe() is assigned to "mgslpc_driver.probe". > > In synclink_cs_init(): > rc = pcmcia_register_driver(&mgslpc_driver); > Thus, mgslpc_probe() can be called after > "pcmcia_register_driver(&mgslpc_driver)". > > As a result, hdlcdev_open() can be executed in synclink_cs_init(). > > **** For mgslpc_open() **** > In synclink_cs_init(): > tty_set_operations(serial_driver, &mgslpc_ops); > rc = tty_register_driver(serial_driver); > Thus, mgslpc_open() can be called after > "tty_register_driver(serial_driver)". > > As a result, mgslpc_open() can be executed in synclink_cs_init(). > > **** For hdlcdev_open() and mgslpc_open() **** > Because mgslpc_open() and hdlcdev_open() can be both executed in > synclink_cs_init(), I think they can be concurrently executed. > > > > > > It's not obvious in looking at the code if this really is the same > > structure or not, how did your tool figure it out? > > My tool uses the data structure field "info->rx_buf" in the code, so it > cannot very accurately figure it out. > > According to my code review, hdlcdev_open() and mgslpc_open() both call > "startup(info, tty)", and rx_alloc_buffers() calls kfree(info->rx_buf). > Thus, an important thing is that whether the variable "info" in > hdlcdev_open() and mgslpc_open() can be the same? > I find this code in hdlcdev_open(): > /* arbitrate between network and tty opens */ > spin_lock_irqsave(&info->netlock, flags); > > Thus, the variable "info" in hdlcdev_open() and mgslpc_open() can be the > same, and "info->rx_buf" in the two calls to kfree() can be the same. > > To fix this bug, I think we can reuse the spinlock "info->netlock" to > protect the function startup() in hdlcdev_open() and mgslpc_open(). > But in rx_alloc_buffers(), there are kmalloc(GFP_KERNEL) and > kzalloc(GFP_KERNEL). > If we reuse the spinlock, we also need to change GFP_KERNEL to GFP_ATOMIC. > What is your opinion? AFAICS, this is a non-issue: If hdlcdev_open() is called, it sets info->netcount=1. If info->netcount!=0, mgslpc_open() will abort before calling startup(). And if mgslpc_open() is called, it sets info->count=1, causing hdlcdev_open() to fail before calling startup(). So no risk of concurrency here. Best, Dominik