From: Oliver Neukum <oneukum@suse.com>
To: Chenyuan Yang <chenyuan0y@gmail.com>,
gregkh@linuxfoundation.org, azeemshaikh38@gmail.com,
ivan.orlov0322@gmail.com, benjamin.tissoires@redhat.com,
linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, syzkaller@googlegroups.com,
Zijie Zhao <zzjas98@gmail.com>
Subject: Re: [Linux Kernel Bug][usb/f_printer] WARNING in usb_ep_queue
Date: Wed, 13 Mar 2024 16:17:38 +0100 [thread overview]
Message-ID: <1196d35e-46a0-4c96-8271-12becb932f06@suse.com> (raw)
In-Reply-To: <CALGdzurBnMztPW1Q8mujfYaopVQ8MkSUXUvnAqJcLGu5ROSU4Q@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 386 bytes --]
On 02.02.24 19:59, Chenyuan Yang wrote:
> Dear Linux Developers for F_printer,
>
> We encountered "WARNING in usb_ep_queue" when testing the f_printer driver with
> Syzkaller and our generated specifications.
>
Hi,
it is clear what happens, but at least to me it is not clear why we allow
a write() before we enable the endpoint. Anyway, does this fix the issue?
Regards
Oliver
[-- Attachment #2: 0001-usb-f_printer-sanity-check-in-write.patch --]
[-- Type: text/x-patch, Size: 3076 bytes --]
From 0008697b8ce373a0378058b60d1f1498c3821330 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@suse.com>
Date: Wed, 13 Mar 2024 16:15:56 +0100
Subject: [PATCH] usb: f_printer: sanity check in write
User space can trigger a write() before the endpoint needed
for that is enabled. Check for that.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/usb/gadget/function/f_printer.c | 37 ++++++++++++++++---------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c
index 076dd4c1be96..1e266ba697e8 100644
--- a/drivers/usb/gadget/function/f_printer.c
+++ b/drivers/usb/gadget/function/f_printer.c
@@ -577,6 +577,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
size_t bytes_copied = 0;
struct usb_request *req;
int value;
+ int err = -ENODEV;
DBG(dev, "printer_write trying to send %d bytes\n", (int)len);
@@ -586,11 +587,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
- if (dev->interface < 0) {
- spin_unlock_irqrestore(&dev->lock, flags);
- mutex_unlock(&dev->lock_printer_io);
- return -ENODEV;
- }
+ if (dev->interface < 0)
+ goto error_spin;
/* Check if a printer reset happens while we have interrupts on */
dev->reset_printer = 0;
@@ -605,8 +603,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
* a NON-Blocking call or not.
*/
if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
- mutex_unlock(&dev->lock_printer_io);
- return -EAGAIN;
+ err = -EAGAIN;
+ goto error_mutex;
}
/* Sleep until a write buffer is available */
@@ -657,9 +655,17 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* We've disconnected or reset so free the req and buffer */
if (dev->reset_printer) {
list_add(&req->list, &dev->tx_reqs);
- spin_unlock_irqrestore(&dev->lock, flags);
- mutex_unlock(&dev->lock_printer_io);
- return -EAGAIN;
+ err = -EAGAIN;
+ goto error_spin;
+ }
+
+ /*
+ * We cannot guarantee user space is using the API nicely
+ * This check needs to be duplicated
+ */
+ if (!dev->in_ep->enabled && dev->in_ep->address) {
+ err = -ESHUTDOWN;
+ goto error_spin;
}
list_add(&req->list, &dev->tx_reqs_active);
@@ -670,9 +676,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
spin_lock(&dev->lock);
if (value) {
list_move(&req->list, &dev->tx_reqs);
- spin_unlock_irqrestore(&dev->lock, flags);
- mutex_unlock(&dev->lock_printer_io);
- return -EAGAIN;
+ err = -EAGAIN;
+ goto error_spin;
}
}
@@ -685,6 +690,12 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
return bytes_copied;
else
return -EAGAIN;
+
+error_spin:
+ spin_unlock_irqrestore(&dev->lock, flags);
+error_mutex:
+ mutex_unlock(&dev->lock_printer_io);
+ return err;
}
static int
--
2.44.0
prev parent reply other threads:[~2024-03-13 15:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-02 18:59 [Linux Kernel Bug][usb/f_printer] WARNING in usb_ep_queue Chenyuan Yang
2024-02-02 21:08 ` Greg KH
2024-03-13 15:17 ` Oliver Neukum [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1196d35e-46a0-4c96-8271-12becb932f06@suse.com \
--to=oneukum@suse.com \
--cc=azeemshaikh38@gmail.com \
--cc=benjamin.tissoires@redhat.com \
--cc=chenyuan0y@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=ivan.orlov0322@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=syzkaller@googlegroups.com \
--cc=zzjas98@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox