Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp1742900ybg; Sat, 19 Oct 2019 01:32:22 -0700 (PDT) X-Google-Smtp-Source: APXvYqyJzNbXK1bwqGIGdwMRFaDN7++8S9n350AJMUPXHoueMOhJiLnBCuE0czPzlXab2El2MejS X-Received: by 2002:a05:6402:2028:: with SMTP id ay8mr13890721edb.273.1571473942722; Sat, 19 Oct 2019 01:32:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571473942; cv=none; d=google.com; s=arc-20160816; b=0mrL1yeB/0WDgBPbTs/ibS84TaZmNngRNboveAvAMThwUFQ5g0PB/Ar9PiluFzHvw6 YtgMWVkZqBVsgkG4YY2lGdfqQ1vvoJGneFDd/0BtMGEjSDfmvWtqIq3kzAAyA372Vktg CRLBSIB8v5id6EDCHOkNwr05IhVB9ASvf1ag+gVT9oth/qfqa4Wi/oEG/k5Zfeu29cbk 4pv7q9Uhcyze+fNLAoREwEdFtvE19GhzBYddo9eZ5WBUXP0CtdxG6aGHYpYfXjXCfoEi OJ3UpL61934ZcNbgZ9L/CuVlAbRzUnjK51fcFJhO+RmIG4ypZztdMAjaL5ZqomZiClWS Al6A== 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=+AnJxrgOsF5pdHMRsdpMSMexStt/hgIWSycUyGA4QAg=; b=BSBmz6Lj7j6149dAsiAMwnRChPtsg88WXdahe1n4Irro5U+1TLktqOa1nCFopNGq/y /UbK1V5XxgOAb/zUtyiRBEKnnPdE2luEZ59r0G37SspAny/xXB+6fc01tTXY7kWRvzM+ P/6NZ+fQ0LNKfoOzvwJZ8ZGcadzgy0Ty4VfpSf2hoXdhEC6R5ugQkqRM14AkfnJ5mOsT OWcwgnjHzxOHIE/PgD5cGJ0QvwYzd/s+cj/GYSTqv72OuQzVx84ii7DJ5lWL+lvQCZKu yEsT/+EjZ7KkuM9aXugVhCBXKjxDSz9BgYJsRs+W+iCJckpWqAsBXLcpEvjb4JNplC0U hgdg== 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 n8si4960712ejh.169.2019.10.19.01.31.59; Sat, 19 Oct 2019 01:32:22 -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 S2632825AbfJRPUH (ORCPT + 99 others); Fri, 18 Oct 2019 11:20:07 -0400 Received: from mail-lf1-f68.google.com ([209.85.167.68]:35527 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2501908AbfJRPUF (ORCPT ); Fri, 18 Oct 2019 11:20:05 -0400 Received: by mail-lf1-f68.google.com with SMTP id w6so5030121lfl.2; Fri, 18 Oct 2019 08:20:02 -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=+AnJxrgOsF5pdHMRsdpMSMexStt/hgIWSycUyGA4QAg=; b=JRFvI3s7v+dr38puTvmC9iBqpU9pPsECM026W3PKld7UNAXFPbFz5r9bdS4GFfP/eG Dy+aWu+AXVRp9HoMfO+UZ3LYoxW/bFdgZrMu898bwULHsJ5fHZtFIOZofdxqRGNbvJ8T NwlybpP7mUpSJgV6QM7b/ioPiyKDi6bea1tYcdVObMF2PFaeUuGUe0QMOykiaUqNGBlp 6M5KOL0N6nP7xQ861JL+sGHvmLghc852AP56TlmdZoK1kWrDihqTQBl+DJMrIGlOHLwh Wdl0LVBv6yXnlcUKqrwk9ceSOaACbTIhidQdyiRJj050D8e8utsKCK6flI56tInSvgkx 121A== X-Gm-Message-State: APjAAAUn7mKJtsJaI4tKF3zZBDXDYxuRLYzJmSE4RxYFUaNWBYsa0lE6 h+VqRAFUoIWIOZ1oYhLe14U= X-Received: by 2002:a19:c6d6:: with SMTP id w205mr5561511lff.17.1571412001935; Fri, 18 Oct 2019 08:20:01 -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 x5sm3197980lfg.71.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-0006YM-6x; 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 Subject: [PATCH RFC v2 2/2] USB: ldusb: fix ring-buffer locking Date: Fri, 18 Oct 2019 17:19:55 +0200 Message-Id: <20191018151955.25135-3-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 The custom ring-buffer implementation was merged without any locking whatsoever, but a spinlock was later added by commit 9d33efd9a791 ("USB: ldusb bugfix"). The lock did not cover the loads from the ring-buffer entry after determining the buffer was non-empty, nor the update of the tail index once the entry had been processed. The former could lead to stale data being returned, while the latter could lead to memory corruption on sufficiently weakly ordered architectures. Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") Fixes: 9d33efd9a791 ("USB: ldusb bugfix") Cc: stable # 2.6.13 Signed-off-by: Johan Hovold --- drivers/usb/misc/ldusb.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 15b5f06fb0b3..6b5843b0071e 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -477,11 +477,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, 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) { + spin_unlock_irq(&dev->rbsl); retval = -EIO; goto unlock_exit; } @@ -489,17 +489,26 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, if (bytes_to_read < *actual_buffer) dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", *actual_buffer-bytes_to_read); + spin_unlock_irq(&dev->rbsl); + + /* + * Pairs with spin_unlock_irqrestore() in + * ld_usb_interrupt_in_callback() and makes sure the ring-buffer entry + * has been updated before copy_to_user(). + */ + smp_rmb(); /* copy one interrupt_in_buffer from ring_buffer into userspace */ if (copy_to_user(buffer, actual_buffer+1, bytes_to_read)) { retval = -EFAULT; goto unlock_exit; } - dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; - retval = bytes_to_read; spin_lock_irq(&dev->rbsl); + + dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; + if (dev->buffer_overflow) { dev->buffer_overflow = 0; spin_unlock_irq(&dev->rbsl); -- 2.23.0