Skip to content

Commit 2c05d88

Browse files
Wenwen Wangdavem330
authored andcommitted
net: cxgb3_main: fix a missing-check bug
In cxgb_extension_ioctl(), the command of the ioctl is firstly copied from the user-space buffer 'useraddr' to 'cmd' and checked through the switch statement. If the command is not as expected, an error code EOPNOTSUPP is returned. In the following execution, i.e., the cases of the switch statement, the whole buffer of 'useraddr' is copied again to a specific data structure, according to what kind of command is requested. However, after the second copy, there is no re-check on the newly-copied command. Given that the buffer 'useraddr' is in the user space, a malicious user can race to change the command between the two copies. By doing so, the attacker can supply malicious data to the kernel and cause undefined behavior. This patch adds a re-check in each case of the switch statement if there is a second copy in that case, to re-check whether the command obtained in the second copy is the same as the one in the first copy. If not, an error code EINVAL is returned. Signed-off-by: Wenwen Wang <wang6495@umn.edu> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b8d5b7c commit 2c05d88

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,6 +2159,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
21592159
return -EPERM;
21602160
if (copy_from_user(&t, useraddr, sizeof(t)))
21612161
return -EFAULT;
2162+
if (t.cmd != CHELSIO_SET_QSET_PARAMS)
2163+
return -EINVAL;
21622164
if (t.qset_idx >= SGE_QSETS)
21632165
return -EINVAL;
21642166
if (!in_range(t.intr_lat, 0, M_NEWTIMER) ||
@@ -2258,6 +2260,9 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
22582260
if (copy_from_user(&t, useraddr, sizeof(t)))
22592261
return -EFAULT;
22602262

2263+
if (t.cmd != CHELSIO_GET_QSET_PARAMS)
2264+
return -EINVAL;
2265+
22612266
/* Display qsets for all ports when offload enabled */
22622267
if (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
22632268
q1 = 0;
@@ -2303,6 +2308,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
23032308
return -EBUSY;
23042309
if (copy_from_user(&edata, useraddr, sizeof(edata)))
23052310
return -EFAULT;
2311+
if (edata.cmd != CHELSIO_SET_QSET_NUM)
2312+
return -EINVAL;
23062313
if (edata.val < 1 ||
23072314
(edata.val > 1 && !(adapter->flags & USING_MSIX)))
23082315
return -EINVAL;
@@ -2343,6 +2350,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
23432350
return -EPERM;
23442351
if (copy_from_user(&t, useraddr, sizeof(t)))
23452352
return -EFAULT;
2353+
if (t.cmd != CHELSIO_LOAD_FW)
2354+
return -EINVAL;
23462355
/* Check t.len sanity ? */
23472356
fw_data = memdup_user(useraddr + sizeof(t), t.len);
23482357
if (IS_ERR(fw_data))
@@ -2366,6 +2375,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
23662375
return -EBUSY;
23672376
if (copy_from_user(&m, useraddr, sizeof(m)))
23682377
return -EFAULT;
2378+
if (m.cmd != CHELSIO_SETMTUTAB)
2379+
return -EINVAL;
23692380
if (m.nmtus != NMTUS)
23702381
return -EINVAL;
23712382
if (m.mtus[0] < 81) /* accommodate SACK */
@@ -2407,6 +2418,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
24072418
return -EBUSY;
24082419
if (copy_from_user(&m, useraddr, sizeof(m)))
24092420
return -EFAULT;
2421+
if (m.cmd != CHELSIO_SET_PM)
2422+
return -EINVAL;
24102423
if (!is_power_of_2(m.rx_pg_sz) ||
24112424
!is_power_of_2(m.tx_pg_sz))
24122425
return -EINVAL; /* not power of 2 */
@@ -2440,6 +2453,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
24402453
return -EIO; /* need the memory controllers */
24412454
if (copy_from_user(&t, useraddr, sizeof(t)))
24422455
return -EFAULT;
2456+
if (t.cmd != CHELSIO_GET_MEM)
2457+
return -EINVAL;
24432458
if ((t.addr & 7) || (t.len & 7))
24442459
return -EINVAL;
24452460
if (t.mem_id == MEM_CM)
@@ -2492,6 +2507,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
24922507
return -EAGAIN;
24932508
if (copy_from_user(&t, useraddr, sizeof(t)))
24942509
return -EFAULT;
2510+
if (t.cmd != CHELSIO_SET_TRACE_FILTER)
2511+
return -EINVAL;
24952512

24962513
tp = (const struct trace_params *)&t.sip;
24972514
if (t.config_tx)

0 commit comments

Comments
 (0)