* [PATCH net] net: usb: pegasus: enable basic endpoint checking
@ 2026-02-22 5:06 Ziyi Guo
2026-02-23 19:50 ` Simon Horman
2026-02-24 11:00 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 3+ messages in thread
From: Ziyi Guo @ 2026-02-22 5:06 UTC (permalink / raw)
To: Petko Manolov, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: linux-usb, netdev, linux-kernel, Ziyi Guo
pegasus_probe() fills URBs with hardcoded endpoint pipes without
verifying the endpoint descriptors:
- usb_rcvbulkpipe(dev, 1) for RX data
- usb_sndbulkpipe(dev, 2) for TX data
- usb_rcvintpipe(dev, 3) for status interrupts
A malformed USB device can present these endpoints with transfer types
that differ from what the driver assumes.
Add a pegasus_usb_ep enum for endpoint numbers, replacing magic
constants throughout. Add usb_check_bulk_endpoints() and
usb_check_int_endpoints() calls before any resource allocation to
verify endpoint types before use, rejecting devices with mismatched
descriptors at probe time, and avoid triggering assertion.
Similar fix to
- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
- commit 9e7021d2aeae ("net: usb: catc: enable basic endpoint checking")
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
---
drivers/net/usb/pegasus.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 7b6d6eb60709..b84968c5f074 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -28,6 +28,17 @@ static const char driver_name[] = "pegasus";
BMSR_100FULL | BMSR_ANEGCAPABLE)
#define CARRIER_CHECK_DELAY (2 * HZ)
+/*
+ * USB endpoints.
+ */
+
+enum pegasus_usb_ep {
+ PEGASUS_USB_EP_CONTROL = 0,
+ PEGASUS_USB_EP_BULK_IN = 1,
+ PEGASUS_USB_EP_BULK_OUT = 2,
+ PEGASUS_USB_EP_INT_IN = 3,
+};
+
static bool loopback;
static bool mii_mode;
static char *devid;
@@ -542,7 +553,7 @@ static void read_bulk_callback(struct urb *urb)
goto tl_sched;
goon:
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
- usb_rcvbulkpipe(pegasus->usb, 1),
+ usb_rcvbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_IN),
pegasus->rx_skb->data, PEGASUS_MTU,
read_bulk_callback, pegasus);
rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
@@ -582,7 +593,7 @@ static void rx_fixup(struct tasklet_struct *t)
return;
}
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
- usb_rcvbulkpipe(pegasus->usb, 1),
+ usb_rcvbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_IN),
pegasus->rx_skb->data, PEGASUS_MTU,
read_bulk_callback, pegasus);
try_again:
@@ -710,7 +721,7 @@ static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb,
((__le16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16);
skb_copy_from_linear_data(skb, pegasus->tx_buff + 2, skb->len);
usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb,
- usb_sndbulkpipe(pegasus->usb, 2),
+ usb_sndbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_OUT),
pegasus->tx_buff, count,
write_bulk_callback, pegasus);
if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
@@ -837,7 +848,7 @@ static int pegasus_open(struct net_device *net)
set_registers(pegasus, EthID, 6, net->dev_addr);
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
- usb_rcvbulkpipe(pegasus->usb, 1),
+ usb_rcvbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_IN),
pegasus->rx_skb->data, PEGASUS_MTU,
read_bulk_callback, pegasus);
if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) {
@@ -848,7 +859,7 @@ static int pegasus_open(struct net_device *net)
}
usb_fill_int_urb(pegasus->intr_urb, pegasus->usb,
- usb_rcvintpipe(pegasus->usb, 3),
+ usb_rcvintpipe(pegasus->usb, PEGASUS_USB_EP_INT_IN),
pegasus->intr_buff, sizeof(pegasus->intr_buff),
intr_callback, pegasus, pegasus->intr_interval);
if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
@@ -1133,10 +1144,24 @@ static int pegasus_probe(struct usb_interface *intf,
pegasus_t *pegasus;
int dev_index = id - pegasus_ids;
int res = -ENOMEM;
+ static const u8 bulk_ep_addr[] = {
+ PEGASUS_USB_EP_BULK_IN | USB_DIR_IN,
+ PEGASUS_USB_EP_BULK_OUT | USB_DIR_OUT,
+ 0};
+ static const u8 int_ep_addr[] = {
+ PEGASUS_USB_EP_INT_IN | USB_DIR_IN,
+ 0};
if (pegasus_blacklisted(dev))
return -ENODEV;
+ /* Verify that all required endpoints are present */
+ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
+ !usb_check_int_endpoints(intf, int_ep_addr)) {
+ dev_err(&intf->dev, "Missing or invalid endpoints\n");
+ return -ENODEV;
+ }
+
net = alloc_etherdev(sizeof(struct pegasus));
if (!net)
goto out;
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net] net: usb: pegasus: enable basic endpoint checking
2026-02-22 5:06 [PATCH net] net: usb: pegasus: enable basic endpoint checking Ziyi Guo
@ 2026-02-23 19:50 ` Simon Horman
2026-02-24 11:00 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 3+ messages in thread
From: Simon Horman @ 2026-02-23 19:50 UTC (permalink / raw)
To: Ziyi Guo
Cc: Petko Manolov, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, linux-usb, netdev, linux-kernel
On Sun, Feb 22, 2026 at 05:06:33AM +0000, Ziyi Guo wrote:
> pegasus_probe() fills URBs with hardcoded endpoint pipes without
> verifying the endpoint descriptors:
>
> - usb_rcvbulkpipe(dev, 1) for RX data
> - usb_sndbulkpipe(dev, 2) for TX data
> - usb_rcvintpipe(dev, 3) for status interrupts
>
> A malformed USB device can present these endpoints with transfer types
> that differ from what the driver assumes.
>
> Add a pegasus_usb_ep enum for endpoint numbers, replacing magic
> constants throughout. Add usb_check_bulk_endpoints() and
> usb_check_int_endpoints() calls before any resource allocation to
> verify endpoint types before use, rejecting devices with mismatched
> descriptors at probe time, and avoid triggering assertion.
>
> Similar fix to
> - commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
> - commit 9e7021d2aeae ("net: usb: catc: enable basic endpoint checking")
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] net: usb: pegasus: enable basic endpoint checking
2026-02-22 5:06 [PATCH net] net: usb: pegasus: enable basic endpoint checking Ziyi Guo
2026-02-23 19:50 ` Simon Horman
@ 2026-02-24 11:00 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-02-24 11:00 UTC (permalink / raw)
To: Ziyi Guo
Cc: petkan, andrew+netdev, davem, edumazet, kuba, pabeni, linux-usb,
netdev, linux-kernel
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Sun, 22 Feb 2026 05:06:33 +0000 you wrote:
> pegasus_probe() fills URBs with hardcoded endpoint pipes without
> verifying the endpoint descriptors:
>
> - usb_rcvbulkpipe(dev, 1) for RX data
> - usb_sndbulkpipe(dev, 2) for TX data
> - usb_rcvintpipe(dev, 3) for status interrupts
>
> [...]
Here is the summary with links:
- [net] net: usb: pegasus: enable basic endpoint checking
https://git.kernel.org/netdev/net/c/3d7e6ce34f4f
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-02-24 10:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-22 5:06 [PATCH net] net: usb: pegasus: enable basic endpoint checking Ziyi Guo
2026-02-23 19:50 ` Simon Horman
2026-02-24 11:00 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox