diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 6 | ||||
-rw-r--r-- | net/core/net_namespace.c | 4 | ||||
-rw-r--r-- | net/core/of_net.c | 33 | ||||
-rw-r--r-- | net/core/sock.c | 5 |
4 files changed, 25 insertions, 23 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 84a0d9542fe9..1baab07820f6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8981,6 +8981,12 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog, goto out_unlock; } old_prog = link->prog; + if (old_prog->type != new_prog->type || + old_prog->expected_attach_type != new_prog->expected_attach_type) { + err = -EINVAL; + goto out_unlock; + } + if (old_prog == new_prog) { /* no-op, don't disturb drivers */ bpf_prog_put(new_prog); diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 9b7171c40434..a5b5bb99c644 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -164,8 +164,10 @@ static void ops_exit_list(const struct pernet_operations *ops, { struct net *net; if (ops->exit) { - list_for_each_entry(net, net_exit_list, exit_list) + list_for_each_entry(net, net_exit_list, exit_list) { ops->exit(net); + cond_resched(); + } } if (ops->exit_batch) ops->exit_batch(net_exit_list); diff --git a/net/core/of_net.c b/net/core/of_net.c index 95a64c813ae5..f1a9bf7578e7 100644 --- a/net/core/of_net.c +++ b/net/core/of_net.c @@ -61,7 +61,7 @@ static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr) { struct platform_device *pdev = of_find_device_by_node(np); struct nvmem_cell *cell; - const void *buf; + const void *mac; size_t len; int ret; @@ -78,32 +78,21 @@ static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr) if (IS_ERR(cell)) return PTR_ERR(cell); - buf = nvmem_cell_read(cell, &len); + mac = nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR(buf)) - return PTR_ERR(buf); - - ret = 0; - if (len == ETH_ALEN) { - if (is_valid_ether_addr(buf)) - memcpy(addr, buf, ETH_ALEN); - else - ret = -EINVAL; - } else if (len == 3 * ETH_ALEN - 1) { - u8 mac[ETH_ALEN]; - - if (mac_pton(buf, mac)) - memcpy(addr, mac, ETH_ALEN); - else - ret = -EINVAL; - } else { - ret = -EINVAL; + if (IS_ERR(mac)) + return PTR_ERR(mac); + + if (len != ETH_ALEN || !is_valid_ether_addr(mac)) { + kfree(mac); + return -EINVAL; } - kfree(buf); + memcpy(addr, mac, ETH_ALEN); + kfree(mac); - return ret; + return 0; } /** diff --git a/net/core/sock.c b/net/core/sock.c index e21485ab285d..4ff806d71921 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -844,6 +844,8 @@ static int sock_timestamping_bind_phc(struct sock *sk, int phc_index) } num = ethtool_get_phc_vclocks(dev, &vclock_index); + dev_put(dev); + for (i = 0; i < num; i++) { if (*(vclock_index + i) == phc_index) { match = true; @@ -2047,6 +2049,9 @@ void sk_destruct(struct sock *sk) { bool use_call_rcu = sock_flag(sk, SOCK_RCU_FREE); + WARN_ON_ONCE(!llist_empty(&sk->defer_list)); + sk_defer_free_flush(sk); + if (rcu_access_pointer(sk->sk_reuseport_cb)) { reuseport_detach_sock(sk); use_call_rcu = true; |