Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp2466548ybg; Sun, 27 Oct 2019 19:17:14 -0700 (PDT) X-Google-Smtp-Source: APXvYqx9SomXLihn1/QdW+4MxXf1uQSxbV2z0qGUSXlhIqrqAvyJOuaTB/zj+uSy9FTise2Oi1H1 X-Received: by 2002:a05:6402:304c:: with SMTP id bu12mr16585514edb.230.1572229034692; Sun, 27 Oct 2019 19:17:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572229034; cv=none; d=google.com; s=arc-20160816; b=uFWPbdb8n0L32E9HgUfc/PHgfTBP3w5JPm2Oc+2lFVp79LxhywqeWwzRyYOdfgCpBa zq7Spmiwv+YAbDZcEquAXapx7cMpXs9o7ZV4BatcsxvexVBprl0YeiXDcOGxbZksKADx s/H44weCONzbwUe/2SXWB0+/exAOJ68RtCEEsmX2+RDyMnNIEdZZDtpOCELTQOSPyS9r A2rehoFoOYq1ZCBBF8hiKvTNvWYWs4nEKkJBFFysDwgS+xEPeufNSNea6ltTN8hP0NQa PQPrLa0dncJgOG2JOHtzgJTRYVbVc6yqnVMru5hPJ0bLn/jopy0MqIgLPVyfVrRl1DIO B8wg== 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=pDUvA+2zg3gUk/rR3jHu/rcGe03Ror2SdrBfCyp2QFo=; b=g+w0Nf6nMctzPJxwgfHA2xMbvd8CoD6VNGwBUeSX6KCc9FVN4iKjwVEvt1EvmikdRW Xx/2AoaaZbKlT55xQUSQCOMyGy3H3zZFwDrys1uQ+H9ifkv2M29Nq4ndLsKe/BvfO/62 HnRbP8+ULGp9wSyToT2w7IPSMloYB4/SdQ9l9+aA7PrX4cifzDkaejDFG+7/NImvao+Q heKZVFq3gnYE9j2zI9zhBePfd0MeeQOcp/PIXG4i6JVP7QandM9gtgwjwg+e6JgbQ3vn fG2Vd6etxwXSrZtTot+Om7f7nMih8HwqzqgXIr22dYblN9h0/YbjqzDGdAT3aUAI4hvg qAtg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=B9PtUTJh; 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 x21si6537638eda.366.2019.10.27.19.16.50; Sun, 27 Oct 2019 19:17:14 -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=B9PtUTJh; 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 S1728101AbfJ0VIa (ORCPT + 99 others); Sun, 27 Oct 2019 17:08:30 -0400 Received: from mail.kernel.org ([198.145.29.99]:54608 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727225AbfJ0VIY (ORCPT ); Sun, 27 Oct 2019 17:08:24 -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 96AF82064A; Sun, 27 Oct 2019 21:08:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1572210503; bh=ZeDfFjrTK0wY0Pvjs0FQCIo/dT7SBq2fX/KyPL6o9GE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B9PtUTJhjY/QeQTbG4QCDKPw/f77JbItCmyv1ICQDpz63/2mSf9mMZ9SqjzZHgJ0U lPMlm5pygm3udYefAlnTowQDMoCI5vsP13jnNrS89kg1bgBa4eUacGfToo9EnaEk1T g5O2sb1rFUNAMY0Sqv+buULpIKxYaymAMmXsVuJk= 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 4.14 036/119] USB: ldusb: fix read info leaks Date: Sun, 27 Oct 2019 22:00:13 +0100 Message-Id: <20191027203311.758225817@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191027203259.948006506@linuxfoundation.org> References: <20191027203259.948006506@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 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -467,7 +467,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) { @@ -477,12 +477,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", @@ -693,7 +698,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(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);