Skip to content

Commit 8518737

Browse files
committed
Merge tag 'usb-5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are some small USB driver fixes for 5.17-rc4 that resolve some reported issues and add new device ids: - usb-serial new device ids - ulpi cleanup fixes - f_fs use-after-free fix - dwc3 driver fixes - ax88179_178a usb network driver fix - usb gadget fixes There is a revert at the end of this series to resolve a build problem that 0-day found yesterday. Most of these have been in linux-next, except for the last few, and all have now passed 0-day tests" * tag 'usb-5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: Revert "usb: dwc2: drd: fix soft connect when gadget is unconfigured" usb: dwc2: drd: fix soft connect when gadget is unconfigured usb: gadget: rndis: check size of RNDIS_MSG_SET command USB: gadget: validate interface OS descriptor requests usb: core: Unregister device on component_add() failure net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup usb: dwc3: gadget: Prevent core from processing stale TRBs USB: serial: cp210x: add CPI Bulk Coin Recycler id USB: serial: cp210x: add NCR Retail IO box id USB: serial: ftdi_sio: add support for Brainboxes US-159/235/320 usb: gadget: f_uac2: Define specific wTerminalType usb: gadget: udc: renesas_usb3: Fix host to USB_ROLE_NONE transition usb: raw-gadget: fix handling of dual-direction-capable endpoints usb: usb251xb: add boost-up property support usb: ulpi: Call of_node_put correctly usb: ulpi: Move of_node_put to ulpi_dev_release USB: serial: option: add ZTE MF286D modem USB: serial: ch341: add support for GW Instek USB2.0-Serial devices usb: f_fs: Fix use-after-free for epfile usb: dwc3: xilinx: fix uninitialized return value
2 parents a4fd49c + 736e8d8 commit 8518737

File tree

17 files changed

+136
-57
lines changed

17 files changed

+136
-57
lines changed

drivers/net/usb/ax88179_178a.c

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,58 +1468,68 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
14681468
u16 hdr_off;
14691469
u32 *pkt_hdr;
14701470

1471-
/* This check is no longer done by usbnet */
1472-
if (skb->len < dev->net->hard_header_len)
1471+
/* At the end of the SKB, there's a header telling us how many packets
1472+
* are bundled into this buffer and where we can find an array of
1473+
* per-packet metadata (which contains elements encoded into u16).
1474+
*/
1475+
if (skb->len < 4)
14731476
return 0;
1474-
14751477
skb_trim(skb, skb->len - 4);
14761478
rx_hdr = get_unaligned_le32(skb_tail_pointer(skb));
1477-
14781479
pkt_cnt = (u16)rx_hdr;
14791480
hdr_off = (u16)(rx_hdr >> 16);
1481+
1482+
if (pkt_cnt == 0)
1483+
return 0;
1484+
1485+
/* Make sure that the bounds of the metadata array are inside the SKB
1486+
* (and in front of the counter at the end).
1487+
*/
1488+
if (pkt_cnt * 2 + hdr_off > skb->len)
1489+
return 0;
14801490
pkt_hdr = (u32 *)(skb->data + hdr_off);
14811491

1482-
while (pkt_cnt--) {
1492+
/* Packets must not overlap the metadata array */
1493+
skb_trim(skb, hdr_off);
1494+
1495+
for (; ; pkt_cnt--, pkt_hdr++) {
14831496
u16 pkt_len;
14841497

14851498
le32_to_cpus(pkt_hdr);
14861499
pkt_len = (*pkt_hdr >> 16) & 0x1fff;
14871500

1488-
/* Check CRC or runt packet */
1489-
if ((*pkt_hdr & AX_RXHDR_CRC_ERR) ||
1490-
(*pkt_hdr & AX_RXHDR_DROP_ERR)) {
1491-
skb_pull(skb, (pkt_len + 7) & 0xFFF8);
1492-
pkt_hdr++;
1493-
continue;
1494-
}
1495-
1496-
if (pkt_cnt == 0) {
1497-
skb->len = pkt_len;
1498-
/* Skip IP alignment pseudo header */
1499-
skb_pull(skb, 2);
1500-
skb_set_tail_pointer(skb, skb->len);
1501-
skb->truesize = pkt_len + sizeof(struct sk_buff);
1502-
ax88179_rx_checksum(skb, pkt_hdr);
1503-
return 1;
1504-
}
1501+
if (pkt_len > skb->len)
1502+
return 0;
15051503

1506-
ax_skb = skb_clone(skb, GFP_ATOMIC);
1507-
if (ax_skb) {
1504+
/* Check CRC or runt packet */
1505+
if (((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) == 0) &&
1506+
pkt_len >= 2 + ETH_HLEN) {
1507+
bool last = (pkt_cnt == 0);
1508+
1509+
if (last) {
1510+
ax_skb = skb;
1511+
} else {
1512+
ax_skb = skb_clone(skb, GFP_ATOMIC);
1513+
if (!ax_skb)
1514+
return 0;
1515+
}
15081516
ax_skb->len = pkt_len;
15091517
/* Skip IP alignment pseudo header */
15101518
skb_pull(ax_skb, 2);
15111519
skb_set_tail_pointer(ax_skb, ax_skb->len);
15121520
ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
15131521
ax88179_rx_checksum(ax_skb, pkt_hdr);
1522+
1523+
if (last)
1524+
return 1;
1525+
15141526
usbnet_skb_return(dev, ax_skb);
1515-
} else {
1516-
return 0;
15171527
}
15181528

1519-
skb_pull(skb, (pkt_len + 7) & 0xFFF8);
1520-
pkt_hdr++;
1529+
/* Trim this packet away from the SKB */
1530+
if (!skb_pull(skb, (pkt_len + 7) & 0xFFF8))
1531+
return 0;
15211532
}
1522-
return 1;
15231533
}
15241534

15251535
static struct sk_buff *

drivers/usb/common/ulpi.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ static const struct attribute_group *ulpi_dev_attr_groups[] = {
130130

131131
static void ulpi_dev_release(struct device *dev)
132132
{
133+
of_node_put(dev->of_node);
133134
kfree(to_ulpi_dev(dev));
134135
}
135136

@@ -247,12 +248,16 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
247248
return ret;
248249

249250
ret = ulpi_read_id(ulpi);
250-
if (ret)
251+
if (ret) {
252+
of_node_put(ulpi->dev.of_node);
251253
return ret;
254+
}
252255

253256
ret = device_register(&ulpi->dev);
254-
if (ret)
257+
if (ret) {
258+
put_device(&ulpi->dev);
255259
return ret;
260+
}
256261

257262
dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
258263
ulpi->id.vendor, ulpi->id.product);
@@ -299,7 +304,6 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface);
299304
*/
300305
void ulpi_unregister_interface(struct ulpi *ulpi)
301306
{
302-
of_node_put(ulpi->dev.of_node);
303307
device_unregister(&ulpi->dev);
304308
}
305309
EXPORT_SYMBOL_GPL(ulpi_unregister_interface);

drivers/usb/core/port.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,14 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
602602
return retval;
603603
}
604604

605-
find_and_link_peer(hub, port1);
606-
607605
retval = component_add(&port_dev->dev, &connector_ops);
608-
if (retval)
606+
if (retval) {
609607
dev_warn(&port_dev->dev, "failed to add component\n");
608+
device_unregister(&port_dev->dev);
609+
return retval;
610+
}
611+
612+
find_and_link_peer(hub, port1);
610613

611614
/*
612615
* Enable runtime pm and hold a refernce that hub_configure()

drivers/usb/dwc3/dwc3-xilinx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
9999
struct device *dev = priv_data->dev;
100100
struct reset_control *crst, *hibrst, *apbrst;
101101
struct phy *usb3_phy;
102-
int ret;
102+
int ret = 0;
103103
u32 reg;
104104

105105
usb3_phy = devm_phy_optional_get(dev, "usb3-phy");

drivers/usb/dwc3/gadget.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,19 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
12911291
if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
12921292
trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(stream_id);
12931293

1294+
/*
1295+
* As per data book 4.2.3.2TRB Control Bit Rules section
1296+
*
1297+
* The controller autonomously checks the HWO field of a TRB to determine if the
1298+
* entire TRB is valid. Therefore, software must ensure that the rest of the TRB
1299+
* is valid before setting the HWO field to '1'. In most systems, this means that
1300+
* software must update the fourth DWORD of a TRB last.
1301+
*
1302+
* However there is a possibility of CPU re-ordering here which can cause
1303+
* controller to observe the HWO bit set prematurely.
1304+
* Add a write memory barrier to prevent CPU re-ordering.
1305+
*/
1306+
wmb();
12941307
trb->ctrl |= DWC3_TRB_CTRL_HWO;
12951308

12961309
dwc3_ep_inc_enq(dep);

drivers/usb/gadget/composite.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
19881988
if (w_index != 0x5 || (w_value >> 8))
19891989
break;
19901990
interface = w_value & 0xFF;
1991+
if (interface >= MAX_CONFIG_INTERFACES ||
1992+
!os_desc_cfg->interface[interface])
1993+
break;
19911994
buf[6] = w_index;
19921995
count = count_ext_prop(os_desc_cfg,
19931996
interface);

drivers/usb/gadget/function/f_fs.c

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,16 +1711,24 @@ static void ffs_data_put(struct ffs_data *ffs)
17111711

17121712
static void ffs_data_closed(struct ffs_data *ffs)
17131713
{
1714+
struct ffs_epfile *epfiles;
1715+
unsigned long flags;
1716+
17141717
ENTER();
17151718

17161719
if (atomic_dec_and_test(&ffs->opened)) {
17171720
if (ffs->no_disconnect) {
17181721
ffs->state = FFS_DEACTIVATED;
1719-
if (ffs->epfiles) {
1720-
ffs_epfiles_destroy(ffs->epfiles,
1721-
ffs->eps_count);
1722-
ffs->epfiles = NULL;
1723-
}
1722+
spin_lock_irqsave(&ffs->eps_lock, flags);
1723+
epfiles = ffs->epfiles;
1724+
ffs->epfiles = NULL;
1725+
spin_unlock_irqrestore(&ffs->eps_lock,
1726+
flags);
1727+
1728+
if (epfiles)
1729+
ffs_epfiles_destroy(epfiles,
1730+
ffs->eps_count);
1731+
17241732
if (ffs->setup_state == FFS_SETUP_PENDING)
17251733
__ffs_ep0_stall(ffs);
17261734
} else {
@@ -1767,14 +1775,27 @@ static struct ffs_data *ffs_data_new(const char *dev_name)
17671775

17681776
static void ffs_data_clear(struct ffs_data *ffs)
17691777
{
1778+
struct ffs_epfile *epfiles;
1779+
unsigned long flags;
1780+
17701781
ENTER();
17711782

17721783
ffs_closed(ffs);
17731784

17741785
BUG_ON(ffs->gadget);
17751786

1776-
if (ffs->epfiles) {
1777-
ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count);
1787+
spin_lock_irqsave(&ffs->eps_lock, flags);
1788+
epfiles = ffs->epfiles;
1789+
ffs->epfiles = NULL;
1790+
spin_unlock_irqrestore(&ffs->eps_lock, flags);
1791+
1792+
/*
1793+
* potential race possible between ffs_func_eps_disable
1794+
* & ffs_epfile_release therefore maintaining a local
1795+
* copy of epfile will save us from use-after-free.
1796+
*/
1797+
if (epfiles) {
1798+
ffs_epfiles_destroy(epfiles, ffs->eps_count);
17781799
ffs->epfiles = NULL;
17791800
}
17801801

@@ -1922,12 +1943,15 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
19221943

19231944
static void ffs_func_eps_disable(struct ffs_function *func)
19241945
{
1925-
struct ffs_ep *ep = func->eps;
1926-
struct ffs_epfile *epfile = func->ffs->epfiles;
1927-
unsigned count = func->ffs->eps_count;
1946+
struct ffs_ep *ep;
1947+
struct ffs_epfile *epfile;
1948+
unsigned short count;
19281949
unsigned long flags;
19291950

19301951
spin_lock_irqsave(&func->ffs->eps_lock, flags);
1952+
count = func->ffs->eps_count;
1953+
epfile = func->ffs->epfiles;
1954+
ep = func->eps;
19311955
while (count--) {
19321956
/* pending requests get nuked */
19331957
if (ep->ep)
@@ -1945,14 +1969,18 @@ static void ffs_func_eps_disable(struct ffs_function *func)
19451969

19461970
static int ffs_func_eps_enable(struct ffs_function *func)
19471971
{
1948-
struct ffs_data *ffs = func->ffs;
1949-
struct ffs_ep *ep = func->eps;
1950-
struct ffs_epfile *epfile = ffs->epfiles;
1951-
unsigned count = ffs->eps_count;
1972+
struct ffs_data *ffs;
1973+
struct ffs_ep *ep;
1974+
struct ffs_epfile *epfile;
1975+
unsigned short count;
19521976
unsigned long flags;
19531977
int ret = 0;
19541978

19551979
spin_lock_irqsave(&func->ffs->eps_lock, flags);
1980+
ffs = func->ffs;
1981+
ep = func->eps;
1982+
epfile = ffs->epfiles;
1983+
count = ffs->eps_count;
19561984
while(count--) {
19571985
ep->ep->driver_data = ep;
19581986

drivers/usb/gadget/function/f_uac2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = {
203203

204204
.bDescriptorSubtype = UAC_INPUT_TERMINAL,
205205
/* .bTerminalID = DYNAMIC */
206-
.wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED),
206+
.wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE),
207207
.bAssocTerminal = 0,
208208
/* .bCSourceID = DYNAMIC */
209209
.iChannelNames = 0,
@@ -231,7 +231,7 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = {
231231

232232
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
233233
/* .bTerminalID = DYNAMIC */
234-
.wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED),
234+
.wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER),
235235
.bAssocTerminal = 0,
236236
/* .bSourceID = DYNAMIC */
237237
/* .bCSourceID = DYNAMIC */

drivers/usb/gadget/function/rndis.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -637,14 +637,17 @@ static int rndis_set_response(struct rndis_params *params,
637637
rndis_set_cmplt_type *resp;
638638
rndis_resp_t *r;
639639

640+
BufLength = le32_to_cpu(buf->InformationBufferLength);
641+
BufOffset = le32_to_cpu(buf->InformationBufferOffset);
642+
if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
643+
(BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
644+
return -EINVAL;
645+
640646
r = rndis_add_response(params, sizeof(rndis_set_cmplt_type));
641647
if (!r)
642648
return -ENOMEM;
643649
resp = (rndis_set_cmplt_type *)r->buf;
644650

645-
BufLength = le32_to_cpu(buf->InformationBufferLength);
646-
BufOffset = le32_to_cpu(buf->InformationBufferOffset);
647-
648651
#ifdef VERBOSE_DEBUG
649652
pr_debug("%s: Length: %d\n", __func__, BufLength);
650653
pr_debug("%s: Offset: %d\n", __func__, BufOffset);

drivers/usb/gadget/legacy/raw_gadget.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io,
10041004
ret = -EBUSY;
10051005
goto out_unlock;
10061006
}
1007-
if ((in && !ep->ep->caps.dir_in) || (!in && ep->ep->caps.dir_in)) {
1007+
if (in != usb_endpoint_dir_in(ep->ep->desc)) {
10081008
dev_dbg(&dev->gadget->dev, "fail, wrong direction\n");
10091009
ret = -EINVAL;
10101010
goto out_unlock;

0 commit comments

Comments
 (0)