mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts
[ Upstream commitf98364e926
] This patch is against CVE-2023-6270. The description of cve is: A flaw was found in the ATA over Ethernet (AoE) driver in the Linux kernel. The aoecmd_cfg_pkts() function improperly updates the refcnt on `struct net_device`, and a use-after-free can be triggered by racing between the free on the struct and the access through the `skbtxq` global queue. This could lead to a denial of service condition or potential code execution. In aoecmd_cfg_pkts(), it always calls dev_put(ifp) when skb initial code is finished. But the net_device ifp will still be used in later tx()->dev_queue_xmit() in kthread. Which means that the dev_put(ifp) should NOT be called in the success path of skb initial code in aoecmd_cfg_pkts(). Otherwise tx() may run into use-after-free because the net_device is freed. This patch removed the dev_put(ifp) in the success path in aoecmd_cfg_pkts(), and added dev_put() after skb xmit in tx(). Link: https://nvd.nist.gov/vuln/detail/CVE-2023-6270 Fixes:7562f876cd
("[NET]: Rework dev_base via list_head (v3)") Signed-off-by: Chun-Yi Lee <jlee@suse.com> Link: https://lore.kernel.org/r/20240305082048.25526-1-jlee@suse.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
59a534690e
commit
eb48680b02
2 changed files with 7 additions and 6 deletions
|
@ -419,13 +419,16 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for_each_netdev_rcu(&init_net, ifp) {
|
for_each_netdev_rcu(&init_net, ifp) {
|
||||||
dev_hold(ifp);
|
dev_hold(ifp);
|
||||||
if (!is_aoe_netif(ifp))
|
if (!is_aoe_netif(ifp)) {
|
||||||
goto cont;
|
dev_put(ifp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
skb = new_skb(sizeof *h + sizeof *ch);
|
skb = new_skb(sizeof *h + sizeof *ch);
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
printk(KERN_INFO "aoe: skb alloc failure\n");
|
printk(KERN_INFO "aoe: skb alloc failure\n");
|
||||||
goto cont;
|
dev_put(ifp);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
skb_put(skb, sizeof *h + sizeof *ch);
|
skb_put(skb, sizeof *h + sizeof *ch);
|
||||||
skb->dev = ifp;
|
skb->dev = ifp;
|
||||||
|
@ -440,9 +443,6 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu
|
||||||
h->major = cpu_to_be16(aoemajor);
|
h->major = cpu_to_be16(aoemajor);
|
||||||
h->minor = aoeminor;
|
h->minor = aoeminor;
|
||||||
h->cmd = AOECMD_CFG;
|
h->cmd = AOECMD_CFG;
|
||||||
|
|
||||||
cont:
|
|
||||||
dev_put(ifp);
|
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ tx(int id) __must_hold(&txlock)
|
||||||
pr_warn("aoe: packet could not be sent on %s. %s\n",
|
pr_warn("aoe: packet could not be sent on %s. %s\n",
|
||||||
ifp ? ifp->name : "netif",
|
ifp ? ifp->name : "netif",
|
||||||
"consider increasing tx_queue_len");
|
"consider increasing tx_queue_len");
|
||||||
|
dev_put(ifp);
|
||||||
spin_lock_irq(&txlock);
|
spin_lock_irq(&txlock);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue