Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp1744521ybg; Sat, 19 Oct 2019 01:34:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqxA6b4V2hTdIGX64K0x0Cx45uXKPw/i7I+4rmRSyhjZ+OktYiH+NF48bHrP/e/Rb0hGtoch X-Received: by 2002:a17:907:4182:: with SMTP id mz2mr12287129ejb.326.1571474058145; Sat, 19 Oct 2019 01:34:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571474058; cv=none; d=google.com; s=arc-20160816; b=Ai7qYRH2oE/z7gGNPwLBjtC/aNXLmRzfh6tjLVKu/Qa8wnF7wXoujGvdVsvxpKUsPG 0jdD3PuFFPmmX2r4g0VqclmPOuF5PBOICfPIDwnFW2LsnLwYfzEeIXFW/cbkKWACZA2Q tFfti2m2g780L8rRPMYXLMD+z46DVzc133mu4LD5w031aXNFDcOEbs0U7bGHnUPvWjip POUJi4EISdHS5Hjr22vVUasU8lwo5VfbeVEqKqjlscFHZNODJGoPL9vmMaNQ0r4cJdas gClLne6YTMdjd622Q2HowAuHroo830vakeNMnO5Ntt6gOjnoceYPP8RMmRzjQQD1Met6 hLDg== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=NWEsXs2dpg7Z5tah6xitYaTbPYgefyb7xkTWhkm2Qdg=; b=nf/rERkuCzPw63MADDVOZHy60FKs4NHnEzTsGfC5RjvWik3BL7HSk5TPj4KiyX5icy rArKC1BQFvPLiG0ruHiM8Vx4QVmeZVND2Muq0TlW6foK5D2tXO/o5M+oH/5UzCDCj3Ul YeX/2Nlyn96ni26HCYuSBGd7aXdzMETbjItEl/wtyTbps6fPKoHPMAAtSKuEY3FrllFw 8MjYfYeQ219eL76c+omVv8yWRZthpomx7LD78gVcjnFrBmoX0feDTZ88hSXGHpHGzPwJ gFkA5ordCF91hGQuwg9wEyDwsZd16AAl+7avyT3uvvNBET48BAGciZDzK/G2IRgRGg9i uqYA== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d15si5486580edb.7.2019.10.19.01.33.55; Sat, 19 Oct 2019 01:34:18 -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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2439631AbfJRPUD (ORCPT + 99 others); Fri, 18 Oct 2019 11:20:03 -0400 Received: from mail-lj1-f194.google.com ([209.85.208.194]:45297 "EHLO mail-lj1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390388AbfJRPUC (ORCPT ); Fri, 18 Oct 2019 11:20:02 -0400 Received: by mail-lj1-f194.google.com with SMTP id q64so6588494ljb.12; Fri, 18 Oct 2019 08:20:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NWEsXs2dpg7Z5tah6xitYaTbPYgefyb7xkTWhkm2Qdg=; b=RIJXSBl/VZkTLWruORCmOEYauiHEoxNiBYt2tKuZuWo4lBqT4RKwWH8clwAetLlSjg y9m2NwyQr9jJdsGN9PLH7CwQN/xbs2xdV40o3grwQQTKvyT4YapYvkIbt6r+px8+HjVC mCHpmTVjT8rLYOqXQmG7cJk+mymp8KYcvcYySfrpAWcWb9w1VbyLh1e8ddWwOntG+2Tl Oqmj3lpgUtKmGrCLHqoOcSowC7iRJjnHQTFPTuQIVjhB7JWAPCQxPenZ/CHXq0AA8oVb BLKneJZAzybZqdvT3kFH6DPvlDDEh36fBk0urlkFYd0wbLAG4iY8lyRwQWAfi7FcgVrb C68g== X-Gm-Message-State: APjAAAVvf9/TaGcCg27mD7loPY48RAtn7hu2vcpREroK3sl+Bt4CQjdx ywArCeBgt9Zw7AYvio//lTMmU/xW X-Received: by 2002:a2e:8e87:: with SMTP id z7mr6588549ljk.9.1571412000231; Fri, 18 Oct 2019 08:20:00 -0700 (PDT) Received: from xi.terra (c-51f1e055.07-184-6d6c6d4.bbcust.telenor.se. [85.224.241.81]) by smtp.gmail.com with ESMTPSA id u21sm5340202lje.92.2019.10.18.08.19.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Oct 2019 08:19:58 -0700 (PDT) Received: from johan by xi.terra with local (Exim 4.92.2) (envelope-from ) id 1iLU31-0006YH-3u; Fri, 18 Oct 2019 17:20:11 +0200 From: Johan Hovold To: Greg Kroah-Hartman Cc: Alan Stern , Oliver Neukum , "Paul E . McKenney" , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold , stable , syzbot+6fe95b826644f7f12b0b@syzkaller.appspotmail.com Subject: [PATCH v2 1/2] USB: ldusb: fix read info leaks Date: Fri, 18 Oct 2019 17:19:54 +0200 Message-Id: <20191018151955.25135-2-johan@kernel.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191018151955.25135-1-johan@kernel.org> References: <20191018151955.25135-1-johan@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/usb/misc/ldusb.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 147c90c2a4e5..15b5f06fb0b3 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -464,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, /* 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 *file, char __user *buffer, size_t count, 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_interface *intf, const struct usb_device_id * 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); -- 2.23.0