Skip to content

Commit 8a160e2

Browse files
petkomanolovdavem330
authored andcommitted
net: usb: pegasus: Check the return value of get_geristers() and friends;
Certain call sites of get_geristers() did not do proper error handling. This could be a problem as get_geristers() typically return the data via pointer to a buffer. If an error occurred the code is carelessly manipulating the wrong data. Signed-off-by: Petko Manolov <[email protected]> Reviewed-by: Pavel Skripkin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 13a9c4a commit 8a160e2

File tree

1 file changed

+75
-33
lines changed

1 file changed

+75
-33
lines changed

drivers/net/usb/pegasus.c

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,15 @@ static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
132132
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
133133
const void *data)
134134
{
135-
return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS,
135+
int ret;
136+
137+
ret = usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS,
136138
PEGASUS_REQT_WRITE, 0, indx, data, size,
137139
1000, GFP_NOIO);
140+
if (ret < 0)
141+
netif_dbg(pegasus, drv, pegasus->net, "%s failed with %d\n", __func__, ret);
142+
143+
return ret;
138144
}
139145

140146
/*
@@ -145,10 +151,15 @@ static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
145151
static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
146152
{
147153
void *buf = &data;
154+
int ret;
148155

149-
return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG,
156+
ret = usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG,
150157
PEGASUS_REQT_WRITE, data, indx, buf, 1,
151158
1000, GFP_NOIO);
159+
if (ret < 0)
160+
netif_dbg(pegasus, drv, pegasus->net, "%s failed with %d\n", __func__, ret);
161+
162+
return ret;
152163
}
153164

154165
static int update_eth_regs_async(pegasus_t *pegasus)
@@ -188,10 +199,9 @@ static int update_eth_regs_async(pegasus_t *pegasus)
188199

189200
static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd)
190201
{
191-
int i;
192-
__u8 data[4] = { phy, 0, 0, indx };
202+
int i, ret;
193203
__le16 regdi;
194-
int ret = -ETIMEDOUT;
204+
__u8 data[4] = { phy, 0, 0, indx };
195205

196206
if (cmd & PHY_WRITE) {
197207
__le16 *t = (__le16 *) & data[1];
@@ -207,12 +217,15 @@ static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd)
207217
if (data[0] & PHY_DONE)
208218
break;
209219
}
210-
if (i >= REG_TIMEOUT)
220+
if (i >= REG_TIMEOUT) {
221+
ret = -ETIMEDOUT;
211222
goto fail;
223+
}
212224
if (cmd & PHY_READ) {
213225
ret = get_registers(p, PhyData, 2, &regdi);
226+
if (ret < 0)
227+
goto fail;
214228
*regd = le16_to_cpu(regdi);
215-
return ret;
216229
}
217230
return 0;
218231
fail:
@@ -235,9 +248,13 @@ static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd)
235248
static int mdio_read(struct net_device *dev, int phy_id, int loc)
236249
{
237250
pegasus_t *pegasus = netdev_priv(dev);
251+
int ret;
238252
u16 res;
239253

240-
read_mii_word(pegasus, phy_id, loc, &res);
254+
ret = read_mii_word(pegasus, phy_id, loc, &res);
255+
if (ret < 0)
256+
return ret;
257+
241258
return (int)res;
242259
}
243260

@@ -251,32 +268,35 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
251268

252269
static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata)
253270
{
254-
int i;
255-
__u8 tmp = 0;
271+
int ret, i;
256272
__le16 retdatai;
257-
int ret;
273+
__u8 tmp = 0;
258274

259275
set_register(pegasus, EpromCtrl, 0);
260276
set_register(pegasus, EpromOffset, index);
261277
set_register(pegasus, EpromCtrl, EPROM_READ);
262278

263279
for (i = 0; i < REG_TIMEOUT; i++) {
264280
ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
281+
if (ret < 0)
282+
goto fail;
265283
if (tmp & EPROM_DONE)
266284
break;
267-
if (ret == -ESHUTDOWN)
268-
goto fail;
269285
}
270-
if (i >= REG_TIMEOUT)
286+
if (i >= REG_TIMEOUT) {
287+
ret = -ETIMEDOUT;
271288
goto fail;
289+
}
272290

273291
ret = get_registers(pegasus, EpromData, 2, &retdatai);
292+
if (ret < 0)
293+
goto fail;
274294
*retdata = le16_to_cpu(retdatai);
275295
return ret;
276296

277297
fail:
278-
netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
279-
return -ETIMEDOUT;
298+
netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__);
299+
return ret;
280300
}
281301

282302
#ifdef PEGASUS_WRITE_EEPROM
@@ -324,10 +344,10 @@ static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data)
324344
return ret;
325345

326346
fail:
327-
netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
347+
netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__);
328348
return -ETIMEDOUT;
329349
}
330-
#endif /* PEGASUS_WRITE_EEPROM */
350+
#endif /* PEGASUS_WRITE_EEPROM */
331351

332352
static inline int get_node_id(pegasus_t *pegasus, u8 *id)
333353
{
@@ -367,19 +387,21 @@ static void set_ethernet_addr(pegasus_t *pegasus)
367387
return;
368388
err:
369389
eth_hw_addr_random(pegasus->net);
370-
dev_info(&pegasus->intf->dev, "software assigned MAC address.\n");
390+
netif_dbg(pegasus, drv, pegasus->net, "software assigned MAC address.\n");
371391

372392
return;
373393
}
374394

375395
static inline int reset_mac(pegasus_t *pegasus)
376396
{
397+
int ret, i;
377398
__u8 data = 0x8;
378-
int i;
379399

380400
set_register(pegasus, EthCtrl1, data);
381401
for (i = 0; i < REG_TIMEOUT; i++) {
382-
get_registers(pegasus, EthCtrl1, 1, &data);
402+
ret = get_registers(pegasus, EthCtrl1, 1, &data);
403+
if (ret < 0)
404+
goto fail;
383405
if (~data & 0x08) {
384406
if (loopback)
385407
break;
@@ -402,22 +424,29 @@ static inline int reset_mac(pegasus_t *pegasus)
402424
}
403425
if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
404426
__u16 auxmode;
405-
read_mii_word(pegasus, 3, 0x1b, &auxmode);
427+
ret = read_mii_word(pegasus, 3, 0x1b, &auxmode);
428+
if (ret < 0)
429+
goto fail;
406430
auxmode |= 4;
407431
write_mii_word(pegasus, 3, 0x1b, &auxmode);
408432
}
409433

410434
return 0;
435+
fail:
436+
netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__);
437+
return ret;
411438
}
412439

413440
static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
414441
{
415-
__u16 linkpart;
416-
__u8 data[4];
417442
pegasus_t *pegasus = netdev_priv(dev);
418443
int ret;
444+
__u16 linkpart;
445+
__u8 data[4];
419446

420-
read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart);
447+
ret = read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart);
448+
if (ret < 0)
449+
goto fail;
421450
data[0] = 0xc8; /* TX & RX enable, append status, no CRC */
422451
data[1] = 0;
423452
if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL))
@@ -435,21 +464,26 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
435464
usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 ||
436465
usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
437466
u16 auxmode;
438-
read_mii_word(pegasus, 0, 0x1b, &auxmode);
467+
ret = read_mii_word(pegasus, 0, 0x1b, &auxmode);
468+
if (ret < 0)
469+
goto fail;
439470
auxmode |= 4;
440471
write_mii_word(pegasus, 0, 0x1b, &auxmode);
441472
}
442473

474+
return 0;
475+
fail:
476+
netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__);
443477
return ret;
444478
}
445479

446480
static void read_bulk_callback(struct urb *urb)
447481
{
448482
pegasus_t *pegasus = urb->context;
449483
struct net_device *net;
484+
u8 *buf = urb->transfer_buffer;
450485
int rx_status, count = urb->actual_length;
451486
int status = urb->status;
452-
u8 *buf = urb->transfer_buffer;
453487
__u16 pkt_len;
454488

455489
if (!pegasus)
@@ -998,8 +1032,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
9981032
data[0] = pegasus->phy;
9991033
fallthrough;
10001034
case SIOCDEVPRIVATE + 1:
1001-
read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]);
1002-
res = 0;
1035+
res = read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]);
10031036
break;
10041037
case SIOCDEVPRIVATE + 2:
10051038
if (!capable(CAP_NET_ADMIN))
@@ -1033,22 +1066,25 @@ static void pegasus_set_multicast(struct net_device *net)
10331066

10341067
static __u8 mii_phy_probe(pegasus_t *pegasus)
10351068
{
1036-
int i;
1069+
int i, ret;
10371070
__u16 tmp;
10381071

10391072
for (i = 0; i < 32; i++) {
1040-
read_mii_word(pegasus, i, MII_BMSR, &tmp);
1073+
ret = read_mii_word(pegasus, i, MII_BMSR, &tmp);
1074+
if (ret < 0)
1075+
goto fail;
10411076
if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0)
10421077
continue;
10431078
else
10441079
return i;
10451080
}
1046-
1081+
fail:
10471082
return 0xff;
10481083
}
10491084

10501085
static inline void setup_pegasus_II(pegasus_t *pegasus)
10511086
{
1087+
int ret;
10521088
__u8 data = 0xa5;
10531089

10541090
set_register(pegasus, Reg1d, 0);
@@ -1060,7 +1096,9 @@ static inline void setup_pegasus_II(pegasus_t *pegasus)
10601096
set_register(pegasus, Reg7b, 2);
10611097

10621098
set_register(pegasus, 0x83, data);
1063-
get_registers(pegasus, 0x83, 1, &data);
1099+
ret = get_registers(pegasus, 0x83, 1, &data);
1100+
if (ret < 0)
1101+
goto fail;
10641102

10651103
if (data == 0xa5)
10661104
pegasus->chip = 0x8513;
@@ -1075,6 +1113,10 @@ static inline void setup_pegasus_II(pegasus_t *pegasus)
10751113
set_register(pegasus, Reg81, 6);
10761114
else
10771115
set_register(pegasus, Reg81, 2);
1116+
1117+
return;
1118+
fail:
1119+
netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__);
10781120
}
10791121

10801122
static void check_carrier(struct work_struct *work)

0 commit comments

Comments
 (0)