mirror of https://gitee.com/openkylin/linux.git
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net 1) Fix combination of --reap and --update in xt_recent that triggers UAF, from Jozsef Kadlecsik. 2) Fix current year in nft_meta selftest, from Fabian Frederick. 3) Fix possible UAF in the netns destroy path of nftables. 4) Fix incorrect checksum calculation when mangling ports in flowtable, from Sven Auhagen. * git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf: netfilter: flowtable: fix tcp and udp header checksum update netfilter: nftables: fix possible UAF over chains from packet path in netns selftests: netfilter: fix current year netfilter: xt_recent: Fix attempt to update deleted entry ==================== Link: https://lore.kernel.org/r/20210205001727.2125-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
b3d2c7b876
|
@ -399,7 +399,7 @@ static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
|
|||
return -1;
|
||||
|
||||
tcph = (void *)(skb_network_header(skb) + thoff);
|
||||
inet_proto_csum_replace2(&tcph->check, skb, port, new_port, true);
|
||||
inet_proto_csum_replace2(&tcph->check, skb, port, new_port, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff,
|
|||
udph = (void *)(skb_network_header(skb) + thoff);
|
||||
if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
inet_proto_csum_replace2(&udph->check, skb, port,
|
||||
new_port, true);
|
||||
new_port, false);
|
||||
if (!udph->check)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
}
|
||||
|
|
|
@ -8949,6 +8949,17 @@ int __nft_release_basechain(struct nft_ctx *ctx)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(__nft_release_basechain);
|
||||
|
||||
static void __nft_release_hooks(struct net *net)
|
||||
{
|
||||
struct nft_table *table;
|
||||
struct nft_chain *chain;
|
||||
|
||||
list_for_each_entry(table, &net->nft.tables, list) {
|
||||
list_for_each_entry(chain, &table->chains, list)
|
||||
nf_tables_unregister_hook(net, table, chain);
|
||||
}
|
||||
}
|
||||
|
||||
static void __nft_release_tables(struct net *net)
|
||||
{
|
||||
struct nft_flowtable *flowtable, *nf;
|
||||
|
@ -8964,10 +8975,6 @@ static void __nft_release_tables(struct net *net)
|
|||
|
||||
list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
|
||||
ctx.family = table->family;
|
||||
|
||||
list_for_each_entry(chain, &table->chains, list)
|
||||
nf_tables_unregister_hook(net, table, chain);
|
||||
/* No packets are walking on these chains anymore. */
|
||||
ctx.table = table;
|
||||
list_for_each_entry(chain, &table->chains, list) {
|
||||
ctx.chain = chain;
|
||||
|
@ -9016,6 +9023,11 @@ static int __net_init nf_tables_init_net(struct net *net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __net_exit nf_tables_pre_exit_net(struct net *net)
|
||||
{
|
||||
__nft_release_hooks(net);
|
||||
}
|
||||
|
||||
static void __net_exit nf_tables_exit_net(struct net *net)
|
||||
{
|
||||
mutex_lock(&net->nft.commit_mutex);
|
||||
|
@ -9029,8 +9041,9 @@ static void __net_exit nf_tables_exit_net(struct net *net)
|
|||
}
|
||||
|
||||
static struct pernet_operations nf_tables_net_ops = {
|
||||
.init = nf_tables_init_net,
|
||||
.exit = nf_tables_exit_net,
|
||||
.init = nf_tables_init_net,
|
||||
.pre_exit = nf_tables_pre_exit_net,
|
||||
.exit = nf_tables_exit_net,
|
||||
};
|
||||
|
||||
static int __init nf_tables_module_init(void)
|
||||
|
|
|
@ -152,7 +152,8 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
|
|||
/*
|
||||
* Drop entries with timestamps older then 'time'.
|
||||
*/
|
||||
static void recent_entry_reap(struct recent_table *t, unsigned long time)
|
||||
static void recent_entry_reap(struct recent_table *t, unsigned long time,
|
||||
struct recent_entry *working, bool update)
|
||||
{
|
||||
struct recent_entry *e;
|
||||
|
||||
|
@ -161,6 +162,12 @@ static void recent_entry_reap(struct recent_table *t, unsigned long time)
|
|||
*/
|
||||
e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
|
||||
|
||||
/*
|
||||
* Do not reap the entry which are going to be updated.
|
||||
*/
|
||||
if (e == working && update)
|
||||
return;
|
||||
|
||||
/*
|
||||
* The last time stamp is the most recent.
|
||||
*/
|
||||
|
@ -303,7 +310,8 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
|
||||
/* info->seconds must be non-zero */
|
||||
if (info->check_set & XT_RECENT_REAP)
|
||||
recent_entry_reap(t, time);
|
||||
recent_entry_reap(t, time, e,
|
||||
info->check_set & XT_RECENT_UPDATE && ret);
|
||||
}
|
||||
|
||||
if (info->check_set & XT_RECENT_SET ||
|
||||
|
|
|
@ -23,7 +23,7 @@ ip -net "$ns0" addr add 127.0.0.1 dev lo
|
|||
|
||||
trap cleanup EXIT
|
||||
|
||||
currentyear=$(date +%G)
|
||||
currentyear=$(date +%Y)
|
||||
lastyear=$((currentyear-1))
|
||||
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
|
||||
table inet filter {
|
||||
|
|
Loading…
Reference in New Issue