From: Zekun Shen <redacted>
[ Upstream commit b922f622592af76b57cbc566eaeccda0b31a3496 ]
This bug report shows up when running our research tools. The
reports is SOOB read, but it seems SOOB write is also possible
a few lines below.
In details, fw.len and sw.len are inputs coming from io. A len
over the size of self->rpc triggers SOOB. The patch fixes the
bugs by adding sanity checks.
The bugs are triggerable with compromised/malfunctioning devices.
They are potentially exploitable given they first leak up to
0xffff bytes and able to overwrite the region later.
The patch is tested with QEMU emulater.
This is NOT tested with a real device.
Attached is the log we found by fuzzing.
BUG: KASAN: slab-out-of-bounds in
hw_atl_utils_fw_upload_dwords+0x393/0x3c0 [atlantic]
Read of size 4 at addr ffff888016260b08 by task modprobe/213
CPU: 0 PID: 213 Comm: modprobe Not tainted 5.6.0 #1
Call Trace:
dump_stack+0x76/0xa0
print_address_description.constprop.0+0x16/0x200
? hw_atl_utils_fw_upload_dwords+0x393/0x3c0 [atlantic]
? hw_atl_utils_fw_upload_dwords+0x393/0x3c0 [atlantic]
__kasan_report.cold+0x37/0x7c
? aq_hw_read_reg_bit+0x60/0x70 [atlantic]
? hw_atl_utils_fw_upload_dwords+0x393/0x3c0 [atlantic]
kasan_report+0xe/0x20
hw_atl_utils_fw_upload_dwords+0x393/0x3c0 [atlantic]
hw_atl_utils_fw_rpc_call+0x95/0x130 [atlantic]
hw_atl_utils_fw_rpc_wait+0x176/0x210 [atlantic]
hw_atl_utils_mpi_create+0x229/0x2e0 [atlantic]
? hw_atl_utils_fw_rpc_wait+0x210/0x210 [atlantic]
? hw_atl_utils_initfw+0x9f/0x1c8 [atlantic]
hw_atl_utils_initfw+0x12a/0x1c8 [atlantic]
aq_nic_ndev_register+0x88/0x650 [atlantic]
? aq_nic_ndev_init+0x235/0x3c0 [atlantic]
aq_pci_probe+0x731/0x9b0 [atlantic]
? aq_pci_func_init+0xc0/0xc0 [atlantic]
local_pci_probe+0xd3/0x160
pci_device_probe+0x23f/0x3e0
Reported-by: Brendan Dolan-Gavitt <redacted>
Signed-off-by: Zekun Shen <redacted>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 10 ++++++++++
1 file changed, 10 insertions(+)
From: Teng Qi <redacted>
[ Upstream commit a66998e0fbf213d47d02813b9679426129d0d114 ]
The if statement:
if (port >= DSAF_GE_NUM)
return;
limits the value of port less than DSAF_GE_NUM (i.e., 8).
However, if the value of port is 6 or 7, an array overflow could occur:
port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
because the length of dsaf_dev->mac_cb is DSAF_MAX_PORT_NUM (i.e., 6).
To fix this possible array overflow, we first check port and if it is
greater than or equal to DSAF_MAX_PORT_NUM, the function returns.
Reported-by: TOTE Robot <redacted>
Signed-off-by: Teng Qi <redacted>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 4 ++++
1 file changed, 4 insertions(+)
@@ -336,6 +336,10 @@ static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,return;if(!HNS_DSAF_IS_DEBUG(dsaf_dev)){+/* DSAF_MAX_PORT_NUM is 6, but DSAF_GE_NUM is 8.+Weneedchecktopreventarrayoverflow*/+if(port>=DSAF_MAX_PORT_NUM)+return;reg_val_1=0x1<<port;port_rst_off=dsaf_dev->mac_cb[port]->port_rst_off;/* there is difference between V1 and V2 in register.*/
From: Teng Qi <redacted>
[ Upstream commit 0fa68da72c3be09e06dd833258ee89c33374195f ]
The definition of macro MOTO_SROM_BUG is:
#define MOTO_SROM_BUG (lp->active == 8 && (get_unaligned_le32(
dev->dev_addr) & 0x00ffffff) == 0x3e0008)
and the if statement
if (MOTO_SROM_BUG) lp->active = 0;
using this macro indicates lp->active could be 8. If lp->active is 8 and
the second comparison of this macro is false. lp->active will remain 8 in:
lp->phy[lp->active].gep = (*p ? p : NULL); p += (2 * (*p) + 1);
lp->phy[lp->active].rst = (*p ? p : NULL); p += (2 * (*p) + 1);
lp->phy[lp->active].mc = get_unaligned_le16(p); p += 2;
lp->phy[lp->active].ana = get_unaligned_le16(p); p += 2;
lp->phy[lp->active].fdx = get_unaligned_le16(p); p += 2;
lp->phy[lp->active].ttm = get_unaligned_le16(p); p += 2;
lp->phy[lp->active].mci = *p;
However, the length of array lp->phy is 8, so array overflows can occur.
To fix these possible array overflows, we first check lp->active and then
return -EINVAL if it is greater or equal to ARRAY_SIZE(lp->phy) (i.e. 8).
Reported-by: TOTE Robot <redacted>
Signed-off-by: Teng Qi <redacted>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/dec/tulip/de4x5.c | 4 ++++
1 file changed, 4 insertions(+)
From: zhangyue <redacted>
[ Upstream commit 61217be886b5f7402843677e4be7e7e83de9cb41 ]
In line 5001, if all id in the array 'lp->phy[8]' is not 0, when the
'for' end, the 'k' is 8.
At this time, the array 'lp->phy[8]' may be out of bound.
Signed-off-by: zhangyue <redacted>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/dec/tulip/de4x5.c | 30 +++++++++++++++-----------
1 file changed, 17 insertions(+), 13 deletions(-)
@@ -4994,19 +4994,23 @@ mii_get_phy(struct net_device *dev)}if((j==limit)&&(i<DE4X5_MAX_MII)){for(k=0;k<DE4X5_MAX_PHY&&lp->phy[k].id;k++);-lp->phy[k].addr=i;-lp->phy[k].id=id;-lp->phy[k].spd.reg=GENERIC_REG;/* ANLPA register */-lp->phy[k].spd.mask=GENERIC_MASK;/* 100Mb/s technologies */-lp->phy[k].spd.value=GENERIC_VALUE;/* TX & T4, H/F Duplex */-lp->mii_cnt++;-lp->active++;-printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n",dev->name);-j=de4x5_debug;-de4x5_debug|=DEBUG_MII;-de4x5_dbg_mii(dev,k);-de4x5_debug=j;-printk("\n");+if(k<DE4X5_MAX_PHY){+lp->phy[k].addr=i;+lp->phy[k].id=id;+lp->phy[k].spd.reg=GENERIC_REG;/* ANLPA register */+lp->phy[k].spd.mask=GENERIC_MASK;/* 100Mb/s technologies */+lp->phy[k].spd.value=GENERIC_VALUE;/* TX & T4, H/F Duplex */+lp->mii_cnt++;+lp->active++;+printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n",dev->name);+j=de4x5_debug;+de4x5_debug|=DEBUG_MII;+de4x5_dbg_mii(dev,k);+de4x5_debug=j;+printk("\n");+}else{+gotopurgatory;+}}}purgatory: