mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
netfilter pull request 26-09-11
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmqj4z4ACgkQ1w0aZmrP KyFvYw//RFZnFWU4PPLMWFiHCKfBQXaDwCM6ADS2phgVLTLbs0OEQ8Mw+XvkOt2v ardyCu5Ujy7udvF2kaha0ACNw+Z3DYOVu+VkzhKJ4TrBaKhr9kob6Vuczdw3QQ10 Kx6UAh3PYWV2BHqB+IoNzd40PBVTHs2ckeSntUNJ1nkGQb2f+kkjWLj3tY+OwaUv fUlD2e34GXdQDEAvYaRHn7Lkv+PMXx4r40EQ238yH9+wTtqBIgCRogTbLHQ3d1Lu r9RHMqHBOkJu5C+gDcVD1r7TXf6S1wBcohEGSvNO+VwF5KDHNylQYS/ONrnUgvRL 9Mr9GmYXgwLN9FxNjYxlo7cjipXHvpONMJ4B0+iz1VE0SL0Z4BNqfpBISqsWW9xP Ox3l4IjnV0Ver+tBcNml6JcwGip1cggHrIi9lb1Zf4cMk+ndq3O+sSSW+EFpKpDn szu9mUrAaHpVOEHUeFqTYjC/Xvq1x1W7QkZ5BqNo4jycROhnRWeWvvUSebW1ruL+ exWYMVA0w3aXPN6tfjGlHMCUuCgMLpOkSvXBgPKIILqnH7rueT5Qhh6wDqpD9NkW xaY1J56MEuhzn2Cf8YkVDdtSgXHc9dteRmg/dLLhnubycewEjDYZTm0vGnLDBYVb 0xvVzNBQm8e7oEoczZQI9Z8Q83Pqi+OhVopZRc7SRaqJCH3pAUU= =H3Kp -----END PGP SIGNATURE----- Merge tag 'nf-26-09-11' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter fixes for net 1) Fix KMSAN reports an uninit-value in nf_nat_setup_info() for netmap, from Theodor Arsenij Larionov Trichkine. 2) Restrict deletion of netdevice in basechain and flowtable to exact matching only, from Fernando F. Mancera. 3) Fix nf_nat_register_fn() error path allowing for a memleak. 4) Hold reference on ct until flow is released to address, otherwise access to release ct->ext or different ct due to typesafe RCU semantics. * tag 'nf-26-09-11' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: flowtable: hold reference on ct until flow is released netfilter: nf_nat: unregister and release hooks on error netfilter: nf_tables: fix device name and prefix match in hook lookup netfilter: nft_nat: fully initialise new_addr in netmap setup ==================== Link: https://patch.msgid.link/20260913205447.1889203-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
6c21ebc813
|
|
@ -258,6 +258,14 @@ static void flow_offload_route_release(struct flow_offload *flow)
|
|||
nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_REPLY);
|
||||
}
|
||||
|
||||
static void flow_offload_free_rcu(struct rcu_head *rcu_head)
|
||||
{
|
||||
struct flow_offload *flow = container_of(rcu_head, struct flow_offload, rcu_head);
|
||||
|
||||
nf_ct_put(flow->ct);
|
||||
kfree(flow);
|
||||
}
|
||||
|
||||
void flow_offload_free(struct flow_offload *flow)
|
||||
{
|
||||
switch (flow->type) {
|
||||
|
|
@ -267,8 +275,7 @@ void flow_offload_free(struct flow_offload *flow)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
nf_ct_put(flow->ct);
|
||||
kfree_rcu(flow, rcu_head);
|
||||
call_rcu(&flow->rcu_head, flow_offload_free_rcu);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(flow_offload_free);
|
||||
|
||||
|
|
@ -854,6 +861,7 @@ static int __init nf_flow_table_module_init(void)
|
|||
|
||||
static void __exit nf_flow_table_module_exit(void)
|
||||
{
|
||||
rcu_barrier();
|
||||
nf_flow_table_offload_exit();
|
||||
unregister_pernet_subsys(&nf_flow_table_net_ops);
|
||||
kmem_cache_destroy(flow_offload_cachep);
|
||||
|
|
|
|||
|
|
@ -1224,31 +1224,45 @@ int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops,
|
|||
}
|
||||
|
||||
ret = nf_register_net_hooks(net, nat_ops, ops_count);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&nf_nat_proto_mutex);
|
||||
for (i = 0; i < ops_count; i++) {
|
||||
priv = nat_ops[i].priv;
|
||||
kfree_rcu(priv, rcu_head);
|
||||
}
|
||||
kfree_rcu(nat_ops, rcu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nat_proto_net->nat_hook_ops = nat_ops;
|
||||
if (ret < 0)
|
||||
goto err_free_hooks;
|
||||
} else {
|
||||
nat_ops = nat_proto_net->nat_hook_ops;
|
||||
}
|
||||
|
||||
nat_ops = nat_proto_net->nat_hook_ops;
|
||||
priv = nat_ops[hooknum].priv;
|
||||
if (WARN_ON_ONCE(!priv)) {
|
||||
mutex_unlock(&nf_nat_proto_mutex);
|
||||
return -EOPNOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_unregister_hooks;
|
||||
}
|
||||
|
||||
ret = nf_hook_entries_insert_raw(&priv->entries, ops);
|
||||
if (ret == 0)
|
||||
nat_proto_net->users++;
|
||||
if (ret)
|
||||
goto err_unregister_hooks;
|
||||
|
||||
if (!nat_proto_net->nat_hook_ops)
|
||||
nat_proto_net->nat_hook_ops = nat_ops;
|
||||
|
||||
nat_proto_net->users++;
|
||||
|
||||
mutex_unlock(&nf_nat_proto_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_hooks:
|
||||
if (nat_proto_net->nat_hook_ops) {
|
||||
mutex_unlock(&nf_nat_proto_mutex);
|
||||
return ret;
|
||||
}
|
||||
nf_unregister_net_hooks(net, nat_ops, ops_count);
|
||||
err_free_hooks:
|
||||
mutex_unlock(&nf_nat_proto_mutex);
|
||||
for (i = 0; i < ops_count; i++) {
|
||||
priv = nat_ops[i].priv;
|
||||
kfree_rcu(priv, rcu_head);
|
||||
}
|
||||
kfree_rcu(nat_ops, rcu);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2440,11 +2440,14 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
|
|||
}
|
||||
|
||||
static struct nft_hook *nft_hook_list_find(struct list_head *hook_list,
|
||||
const struct nft_hook *this)
|
||||
const struct nft_hook *this,
|
||||
bool strict)
|
||||
{
|
||||
struct nft_hook *hook;
|
||||
|
||||
list_for_each_entry(hook, hook_list, list) {
|
||||
if (strict && hook->ifnamelen != this->ifnamelen)
|
||||
continue;
|
||||
if (!strncmp(hook->ifname, this->ifname,
|
||||
min(hook->ifnamelen, this->ifnamelen))) {
|
||||
if (hook->flags & NFT_HOOK_REMOVE)
|
||||
|
|
@ -2486,7 +2489,7 @@ static int nf_tables_parse_netdev_hooks(struct net *net,
|
|||
err = PTR_ERR(hook);
|
||||
goto err_hook;
|
||||
}
|
||||
if (nft_hook_list_find(hook_list, hook)) {
|
||||
if (nft_hook_list_find(hook_list, hook, false)) {
|
||||
NL_SET_BAD_ATTR(extack, tmp);
|
||||
nft_netdev_hook_free(hook);
|
||||
err = -EEXIST;
|
||||
|
|
@ -2943,7 +2946,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
|
|||
ops->hook = basechain->ops.hook;
|
||||
}
|
||||
|
||||
if (nft_hook_list_find(&basechain->hook_list, h)) {
|
||||
if (nft_hook_list_find(&basechain->hook_list, h, false)) {
|
||||
list_del(&h->list);
|
||||
nft_netdev_hook_free(h);
|
||||
continue;
|
||||
|
|
@ -2956,7 +2959,8 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
|
|||
!nft_trans_chain_update(trans))
|
||||
continue;
|
||||
|
||||
if (nft_hook_list_find(&nft_trans_chain_hooks(trans), h)) {
|
||||
if (nft_hook_list_find(&nft_trans_chain_hooks(trans),
|
||||
h, false)) {
|
||||
nft_chain_release_hook(&hook);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
|
@ -3257,7 +3261,7 @@ static int nft_delchain_hook(struct nft_ctx *ctx,
|
|||
return err;
|
||||
|
||||
list_for_each_entry(this, &chain_hook.list, list) {
|
||||
hook = nft_hook_list_find(&basechain->hook_list, this);
|
||||
hook = nft_hook_list_find(&basechain->hook_list, this, true);
|
||||
if (!hook) {
|
||||
err = -ENOENT;
|
||||
goto err_chain_del_hook;
|
||||
|
|
@ -9053,7 +9057,7 @@ static int nft_register_flowtable_net_hooks(struct net *net,
|
|||
if (!nft_is_active_next(net, ft))
|
||||
continue;
|
||||
|
||||
if (nft_hook_list_find(&ft->hook_list, hook)) {
|
||||
if (nft_hook_list_find(&ft->hook_list, hook, false)) {
|
||||
err = -EEXIST;
|
||||
goto err_unregister_net_hooks;
|
||||
}
|
||||
|
|
@ -9130,7 +9134,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
|
|||
return err;
|
||||
|
||||
list_for_each_entry_safe(hook, next, &flowtable_hook.list, list) {
|
||||
if (nft_hook_list_find(&flowtable->hook_list, hook)) {
|
||||
if (nft_hook_list_find(&flowtable->hook_list, hook, false)) {
|
||||
list_del(&hook->list);
|
||||
nft_netdev_hook_free(hook);
|
||||
continue;
|
||||
|
|
@ -9143,7 +9147,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
|
|||
!nft_trans_flowtable_update(trans))
|
||||
continue;
|
||||
|
||||
if (nft_hook_list_find(&nft_trans_flowtable_hooks(trans), hook)) {
|
||||
if (nft_hook_list_find(&nft_trans_flowtable_hooks(trans), hook, false)) {
|
||||
err = -EEXIST;
|
||||
goto err_flowtable_update_hook;
|
||||
}
|
||||
|
|
@ -9363,7 +9367,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
|
|||
return err;
|
||||
|
||||
list_for_each_entry(this, &flowtable_hook.list, list) {
|
||||
hook = nft_hook_list_find(&flowtable->hook_list, this);
|
||||
hook = nft_hook_list_find(&flowtable->hook_list, this, true);
|
||||
if (!hook) {
|
||||
err = -ENOENT;
|
||||
goto err_flowtable_del_hook;
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ static void nft_nat_setup_netmap(struct nf_nat_range2 *range,
|
|||
const struct nft_pktinfo *pkt,
|
||||
const struct nft_nat *priv)
|
||||
{
|
||||
union nf_inet_addr new_addr = {};
|
||||
struct sk_buff *skb = pkt->skb;
|
||||
union nf_inet_addr new_addr;
|
||||
__be32 netmask;
|
||||
int i, len = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user