IB/core: Fix use after free of ifa
When using ifup/ifdown while executing enum_netdev_ipv4_ips,
ifa could become invalid and cause use after free error.
Fixing it by protecting with RCU lock.
Fixes: 03db3a2d81
('IB/core: Add RoCE GID table management')
Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
17b38fb890
commit
3909642034
1 changed files with 27 additions and 8 deletions
|
@ -250,25 +250,44 @@ static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
|
|||
u8 port, struct net_device *ndev)
|
||||
{
|
||||
struct in_device *in_dev;
|
||||
struct sin_list {
|
||||
struct list_head list;
|
||||
struct sockaddr_in ip;
|
||||
};
|
||||
struct sin_list *sin_iter;
|
||||
struct sin_list *sin_temp;
|
||||
|
||||
LIST_HEAD(sin_list);
|
||||
if (ndev->reg_state >= NETREG_UNREGISTERING)
|
||||
return;
|
||||
|
||||
in_dev = in_dev_get(ndev);
|
||||
if (!in_dev)
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get_rcu(ndev);
|
||||
if (!in_dev) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
for_ifa(in_dev) {
|
||||
struct sockaddr_in ip;
|
||||
struct sin_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
|
||||
|
||||
ip.sin_family = AF_INET;
|
||||
ip.sin_addr.s_addr = ifa->ifa_address;
|
||||
update_gid_ip(GID_ADD, ib_dev, port, ndev,
|
||||
(struct sockaddr *)&ip);
|
||||
if (!entry) {
|
||||
pr_warn("roce_gid_mgmt: couldn't allocate entry for IPv4 update\n");
|
||||
continue;
|
||||
}
|
||||
entry->ip.sin_family = AF_INET;
|
||||
entry->ip.sin_addr.s_addr = ifa->ifa_address;
|
||||
list_add_tail(&entry->list, &sin_list);
|
||||
}
|
||||
endfor_ifa(in_dev);
|
||||
rcu_read_unlock();
|
||||
|
||||
in_dev_put(in_dev);
|
||||
list_for_each_entry_safe(sin_iter, sin_temp, &sin_list, list) {
|
||||
update_gid_ip(GID_ADD, ib_dev, port, ndev,
|
||||
(struct sockaddr *)&sin_iter->ip);
|
||||
list_del(&sin_iter->list);
|
||||
kfree(sin_iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
|
||||
|
|
Loading…
Reference in a new issue