Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp2250765ybg; Sun, 27 Oct 2019 14:23:41 -0700 (PDT) X-Google-Smtp-Source: APXvYqx4/g9It3ifJnCIy9reKQYjLDWXwMUlwazmCBsMNYEzWv7ndNYdFQO3KAjj1CrwAICOjPMa X-Received: by 2002:a17:906:b2c1:: with SMTP id cf1mr13251508ejb.155.1572211421045; Sun, 27 Oct 2019 14:23:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572211421; cv=none; d=google.com; s=arc-20160816; b=uAj0freogLEKVPGcE1NGNrYFIShVGbGa4ifYq8bdyDGvZ2pT3u2vWzV62bkwXaV5nZ DvaCMo5IomE6LhqWXxj18vARqZy3XJK91m43cKvvT735MgINySY5hHmpd7Hsl3g0KO1C oxzk7FbWOYoBm2XoUPERzTxLgBmJFAwzNrRVbRJywJW0FA84KDUlJNhNgYczOaeP+1Io qU6Gf4vWYvvMuNewIgFXLyg0g7Artwe4mT+mOl/kBbIZmfLgJZ0dUvF9u0mWzkBZMMq8 X6r3D8rOWBn0cv1IQy4In07YLDHqRq1l5XQ08yl7wsT2jlGPgDR7kMZBCmuNyw7g4v2c V1+A== 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=rcMa6uWqFhvix099AIaAsfUOT9IaQZJz9OKFYm3O8JY=; b=Qz8ugpnm40t1afld6k4mtEXUv2RZBs61pJq1Z9Yd4SDFSGgfXGeOYel/H0g/c7fN9n 60rJngLbfdxZmOKuE9rCdrxLpyuAnTP+j3X3aHBf1pfEm4zbH3aCJ3EkcGbgAcuJTaUy aWXsvga0e8S5Gnehik0YggGnNo1L5AqXyrNoN6LqsIyZJIfW2laGQGYzJtTN7rOF6pm0 u5t8SawJ0/5OBUfkEC+rJ2ksBzEnqeC/fAOIYTbjKWFdZ6ffd8UImK0eHMmNgStkojPb Z6RSVMBjPZQQbZ2fwazGHE16oWcR21n52d5BhP4uBcETtOyfUC7tC4OmEHCWGrRcDjmE w6fw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ueJwNpga; 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 h56si6433467edh.363.2019.10.27.14.23.17; Sun, 27 Oct 2019 14:23:41 -0700 (PDT) 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=ueJwNpga; 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 S1732006AbfJ0VVv (ORCPT + 99 others); Sun, 27 Oct 2019 17:21:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:42694 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731992AbfJ0VVr (ORCPT ); Sun, 27 Oct 2019 17:21:47 -0400 Received: from localhost (100.50.158.77.rev.sfr.net [77.158.50.100]) (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 0E172205C9; Sun, 27 Oct 2019 21:21:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1572211306; bh=EUuh1vPUFAlhoRbVgQeGEOyNuTvyYkG+7Olaa9exQJU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ueJwNpgaLX/KnAcJFGrGQIZMUOLOI8FTl0taNRaK3RC2F1J1pWYQRwlijA24OYL4a hfZ/VE4FyYJ3IYqsmlUrdibcwYBP+gGkiRRym758RjKBnVdgQD19dLurZ+BUcBDv+v 4Z0OYlU8KhfhOcN3XskQ1cU33jr63siRqcetmIPA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+6fe95b826644f7f12b0b@syzkaller.appspotmail.com, Johan Hovold Subject: [PATCH 5.3 105/197] USB: ldusb: fix read info leaks Date: Sun, 27 Oct 2019 22:00:23 +0100 Message-Id: <20191027203357.428830803@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191027203351.684916567@linuxfoundation.org> References: <20191027203351.684916567@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: Johan Hovold commit 7a6f22d7479b7a0b68eadd308a997dd64dda7dae upstream. Fix broken read implementation, which could be used to trigger slab info leaks. The driver failed to check if the custom ring buffer was still empty when waking up after having waited for more data. This would happen on every interrupt-in completion, even if no data had been added to the ring buffer (e.g. on disconnect events). Due to missing sanity checks and uninitialised (kmalloced) ring-buffer entries, this meant that huge slab info leaks could easily be triggered. Note that the empty-buffer check after wakeup is enough to fix the info leak on disconnect, but let's clear the buffer on allocation and add a sanity check to read() to prevent further leaks. Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") Cc: stable # 2.6.13 Reported-by: syzbot+6fe95b826644f7f12b0b@syzkaller.appspotmail.com Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191018151955.25135-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -464,7 +464,7 @@ static ssize_t ld_usb_read(struct file * /* wait for data */ spin_lock_irq(&dev->rbsl); - if (dev->ring_head == dev->ring_tail) { + while (dev->ring_head == dev->ring_tail) { dev->interrupt_in_done = 0; spin_unlock_irq(&dev->rbsl); if (file->f_flags & O_NONBLOCK) { @@ -474,12 +474,17 @@ static ssize_t ld_usb_read(struct file * retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) goto unlock_exit; - } else { - spin_unlock_irq(&dev->rbsl); + + spin_lock_irq(&dev->rbsl); } + spin_unlock_irq(&dev->rbsl); /* actual_buffer contains actual_length + interrupt_in_buffer */ actual_buffer = (size_t *)(dev->ring_buffer + dev->ring_tail * (sizeof(size_t)+dev->interrupt_in_endpoint_size)); + if (*actual_buffer > dev->interrupt_in_endpoint_size) { + retval = -EIO; + goto unlock_exit; + } bytes_to_read = min(count, *actual_buffer); if (bytes_to_read < *actual_buffer) dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", @@ -690,10 +695,9 @@ static int ld_usb_probe(struct usb_inter dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); - dev->ring_buffer = - kmalloc_array(ring_buffer_size, - sizeof(size_t) + dev->interrupt_in_endpoint_size, - GFP_KERNEL); + dev->ring_buffer = kcalloc(ring_buffer_size, + sizeof(size_t) + dev->interrupt_in_endpoint_size, + GFP_KERNEL); if (!dev->ring_buffer) goto error; dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);