mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-12 08:06:45 +07:00
Merge branch 'master' of git://1984.lsi.us.es/nf-next
Pablo says: ==================== The following patchset provides fixes for issues that were recently introduced by my new cthelper infrastructure. They have been spotted by Randy Dunlap, Andrew Morton and Dan Carpenter. The patches provide: * compilation fixes if CONFIG_NF_CONNTRACK is disabled: I moved all the conntrack code from nfnetlink_queue.c to nfnetlink_queue_ct.c to avoid peppering the entire code with lots of ifdefs. I needed to rename nfnetlink_queue.c to nfnetlink_queue_core.c to get it working with the Makefile tweaks I've added. * fix NULL pointer dereference via ctnetlink while trying to change the helper for an existing conntrack entry. I don't find any reasonable use case for changing the helper from one to another in run-time. Thus, now ctnetlink returns -EOPNOTSUPP for this operation. * fix possible out-of-bound zeroing of the conntrack extension area due to the helper automatic assignation routine. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
6bdc5f49e3
43
include/net/netfilter/nfnetlink_queue.h
Normal file
43
include/net/netfilter/nfnetlink_queue.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef _NET_NFNL_QUEUE_H_
|
||||
#define _NET_NFNL_QUEUE_H_
|
||||
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
|
||||
struct nf_conn;
|
||||
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
|
||||
enum ip_conntrack_info *ctinfo);
|
||||
struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb,
|
||||
const struct nlattr *attr,
|
||||
enum ip_conntrack_info *ctinfo);
|
||||
int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo);
|
||||
void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo, int diff);
|
||||
#else
|
||||
inline struct nf_conn *
|
||||
nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb,
|
||||
const struct nlattr *attr,
|
||||
enum ip_conntrack_info *ctinfo)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline int
|
||||
nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo, int diff)
|
||||
{
|
||||
}
|
||||
#endif /* NF_CONNTRACK */
|
||||
#endif
|
@ -12,14 +12,6 @@ tristate "Netfilter NFACCT over NFNETLINK interface"
|
||||
If this option is enabled, the kernel will include support
|
||||
for extended accounting via NFNETLINK.
|
||||
|
||||
config NETFILTER_NETLINK_CTHELPER
|
||||
tristate "Netfilter CTHELPER over NFNETLINK interface"
|
||||
depends on NETFILTER_ADVANCED
|
||||
select NETFILTER_NETLINK
|
||||
help
|
||||
If this option is enabled, the kernel will include support
|
||||
for user-space connection tracking helpers via NFNETLINK.
|
||||
|
||||
config NETFILTER_NETLINK_QUEUE
|
||||
tristate "Netfilter NFQUEUE over NFNETLINK interface"
|
||||
depends on NETFILTER_ADVANCED
|
||||
@ -343,6 +335,27 @@ config NF_CT_NETLINK_TIMEOUT
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
config NF_CT_NETLINK_HELPER
|
||||
tristate 'Connection tracking helpers in user-space via Netlink'
|
||||
select NETFILTER_NETLINK
|
||||
depends on NF_CT_NETLINK
|
||||
depends on NETFILTER_NETLINK_QUEUE
|
||||
depends on NETFILTER_NETLINK_QUEUE_CT
|
||||
depends on NETFILTER_ADVANCED
|
||||
help
|
||||
This option enables the user-space connection tracking helpers
|
||||
infrastructure.
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
config NETFILTER_NETLINK_QUEUE_CT
|
||||
bool "NFQUEUE integration with Connection Tracking"
|
||||
default n
|
||||
depends on NETFILTER_NETLINK_QUEUE
|
||||
help
|
||||
If this option is enabled, NFQUEUE can include Connection Tracking
|
||||
information together with the packet is the enqueued via NFNETLINK.
|
||||
|
||||
endif # NF_CONNTRACK
|
||||
|
||||
# transparent proxy support
|
||||
|
@ -9,7 +9,8 @@ obj-$(CONFIG_NETFILTER) = netfilter.o
|
||||
|
||||
obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
|
||||
obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
|
||||
obj-$(CONFIG_NETFILTER_NETLINK_CTHELPER) += nfnetlink_cthelper.o
|
||||
nfnetlink_queue-y := nfnetlink_queue_core.o
|
||||
nfnetlink_queue-$(CONFIG_NETFILTER_NETLINK_QUEUE_CT) += nfnetlink_queue_ct.o
|
||||
obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
|
||||
obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
|
||||
|
||||
@ -25,6 +26,7 @@ obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o
|
||||
# netlink interface for nf_conntrack
|
||||
obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
|
||||
obj-$(CONFIG_NF_CT_NETLINK_TIMEOUT) += nfnetlink_cttimeout.o
|
||||
obj-$(CONFIG_NF_CT_NETLINK_HELPER) += nfnetlink_cthelper.o
|
||||
|
||||
# connection tracking helpers
|
||||
nf_conntrack_h323-objs := nf_conntrack_h323_main.o nf_conntrack_h323_asn1.o
|
||||
|
@ -229,7 +229,13 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
memset(help->data, 0, helper->data_len);
|
||||
/* We only allow helper re-assignment of the same sort since
|
||||
* we cannot reallocate the helper extension area.
|
||||
*/
|
||||
if (help->helper != helper) {
|
||||
RCU_INIT_POINTER(help->helper, NULL);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rcu_assign_pointer(help->helper, helper);
|
||||
|
@ -1224,19 +1224,12 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
|
||||
if (helper->from_nlattr && helpinfo)
|
||||
helper->from_nlattr(helpinfo, ct);
|
||||
return 0;
|
||||
}
|
||||
if (help->helper)
|
||||
} else
|
||||
return -EBUSY;
|
||||
/* need to zero data of old helper */
|
||||
memset(help->data, 0, help->helper->data_len);
|
||||
} else {
|
||||
/* we cannot set a helper for an existing conntrack */
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
rcu_assign_pointer(help->helper, helper);
|
||||
|
||||
return 0;
|
||||
/* we cannot set a helper for an existing conntrack */
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -1634,8 +1627,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \
|
||||
defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
|
||||
static size_t
|
||||
ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
|
||||
{
|
||||
@ -1769,7 +1761,7 @@ static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
|
||||
.seq_adjust = nf_nat_tcp_seq_adjust,
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_NETFILTER_NETLINK_QUEUE */
|
||||
#endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */
|
||||
|
||||
/***********************************************************************
|
||||
* EXPECT
|
||||
@ -2575,8 +2567,7 @@ static int __init ctnetlink_init(void)
|
||||
pr_err("ctnetlink_init: cannot register pernet operations\n");
|
||||
goto err_unreg_exp_subsys;
|
||||
}
|
||||
#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \
|
||||
defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
|
||||
/* setup interaction between nf_queue and nf_conntrack_netlink. */
|
||||
RCU_INIT_POINTER(nfq_ct_hook, &ctnetlink_nfqueue_hook);
|
||||
#endif
|
||||
@ -2597,8 +2588,7 @@ static void __exit ctnetlink_exit(void)
|
||||
unregister_pernet_subsys(&ctnetlink_net_ops);
|
||||
nfnetlink_subsys_unregister(&ctnl_exp_subsys);
|
||||
nfnetlink_subsys_unregister(&ctnl_subsys);
|
||||
#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) || \
|
||||
defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
|
||||
RCU_INIT_POINTER(nfq_ct_hook, NULL);
|
||||
#endif
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/netfilter/nf_queue.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nfnetlink_queue.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
||||
@ -234,7 +234,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
|
||||
struct sk_buff *entskb = entry->skb;
|
||||
struct net_device *indev;
|
||||
struct net_device *outdev;
|
||||
struct nfq_ct_hook *nfq_ct;
|
||||
struct nf_conn *ct = NULL;
|
||||
enum ip_conntrack_info uninitialized_var(ctinfo);
|
||||
|
||||
@ -270,17 +269,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
|
||||
break;
|
||||
}
|
||||
|
||||
/* rcu_read_lock()ed by __nf_queue already. */
|
||||
nfq_ct = rcu_dereference(nfq_ct_hook);
|
||||
if (nfq_ct != NULL && (queue->flags & NFQA_CFG_F_CONNTRACK)) {
|
||||
ct = nf_ct_get(entskb, &ctinfo);
|
||||
if (ct) {
|
||||
if (!nf_ct_is_untracked(ct))
|
||||
size += nfq_ct->build_size(ct);
|
||||
else
|
||||
ct = NULL;
|
||||
}
|
||||
}
|
||||
if (queue->flags & NFQA_CFG_F_CONNTRACK)
|
||||
ct = nfqnl_ct_get(entskb, &size, &ctinfo);
|
||||
|
||||
skb = alloc_skb(size, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
@ -404,23 +394,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (ct) {
|
||||
struct nlattr *nest_parms;
|
||||
u_int32_t tmp;
|
||||
|
||||
nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
|
||||
if (!nest_parms)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nfq_ct->build(skb, ct) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
nla_nest_end(skb, nest_parms);
|
||||
|
||||
tmp = ctinfo;
|
||||
if (nla_put_u32(skb, NFQA_CT_INFO, htonl(ctinfo)))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
nlh->nlmsg_len = skb->tail - old_tail;
|
||||
return skb;
|
||||
@ -764,7 +739,6 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
struct nfqnl_instance *queue;
|
||||
unsigned int verdict;
|
||||
struct nf_queue_entry *entry;
|
||||
struct nfq_ct_hook *nfq_ct;
|
||||
enum ip_conntrack_info uninitialized_var(ctinfo);
|
||||
struct nf_conn *ct = NULL;
|
||||
|
||||
@ -786,13 +760,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
return -ENOENT;
|
||||
|
||||
rcu_read_lock();
|
||||
nfq_ct = rcu_dereference(nfq_ct_hook);
|
||||
if (nfq_ct != NULL &&
|
||||
(queue->flags & NFQA_CFG_F_CONNTRACK) && nfqa[NFQA_CT]) {
|
||||
ct = nf_ct_get(entry->skb, &ctinfo);
|
||||
if (ct && !nf_ct_is_untracked(ct))
|
||||
nfq_ct->parse(nfqa[NFQA_CT], ct);
|
||||
}
|
||||
if (nfqa[NFQA_CT] && (queue->flags & NFQA_CFG_F_CONNTRACK))
|
||||
ct = nfqnl_ct_parse(entry->skb, nfqa[NFQA_CT], &ctinfo);
|
||||
|
||||
if (nfqa[NFQA_PAYLOAD]) {
|
||||
u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]);
|
||||
@ -802,8 +771,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
payload_len, entry, diff) < 0)
|
||||
verdict = NF_DROP;
|
||||
|
||||
if (ct && (ct->status & IPS_NAT_MASK) && diff)
|
||||
nfq_ct->seq_adjust(skb, ct, ctinfo, diff);
|
||||
if (ct)
|
||||
nfqnl_ct_seq_adjust(skb, ct, ctinfo, diff);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
97
net/netfilter/nfnetlink_queue_ct.c
Normal file
97
net/netfilter/nfnetlink_queue_ct.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
|
||||
struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
|
||||
enum ip_conntrack_info *ctinfo)
|
||||
{
|
||||
struct nfq_ct_hook *nfq_ct;
|
||||
struct nf_conn *ct;
|
||||
|
||||
/* rcu_read_lock()ed by __nf_queue already. */
|
||||
nfq_ct = rcu_dereference(nfq_ct_hook);
|
||||
if (nfq_ct == NULL)
|
||||
return NULL;
|
||||
|
||||
ct = nf_ct_get(entskb, ctinfo);
|
||||
if (ct) {
|
||||
if (!nf_ct_is_untracked(ct))
|
||||
*size += nfq_ct->build_size(ct);
|
||||
else
|
||||
ct = NULL;
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
struct nf_conn *
|
||||
nfqnl_ct_parse(const struct sk_buff *skb, const struct nlattr *attr,
|
||||
enum ip_conntrack_info *ctinfo)
|
||||
{
|
||||
struct nfq_ct_hook *nfq_ct;
|
||||
struct nf_conn *ct;
|
||||
|
||||
/* rcu_read_lock()ed by __nf_queue already. */
|
||||
nfq_ct = rcu_dereference(nfq_ct_hook);
|
||||
if (nfq_ct == NULL)
|
||||
return NULL;
|
||||
|
||||
ct = nf_ct_get(skb, ctinfo);
|
||||
if (ct && !nf_ct_is_untracked(ct))
|
||||
nfq_ct->parse(attr, ct);
|
||||
|
||||
return ct;
|
||||
}
|
||||
|
||||
int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
struct nfq_ct_hook *nfq_ct;
|
||||
struct nlattr *nest_parms;
|
||||
u_int32_t tmp;
|
||||
|
||||
nfq_ct = rcu_dereference(nfq_ct_hook);
|
||||
if (nfq_ct == NULL)
|
||||
return 0;
|
||||
|
||||
nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
|
||||
if (!nest_parms)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nfq_ct->build(skb, ct) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
nla_nest_end(skb, nest_parms);
|
||||
|
||||
tmp = ctinfo;
|
||||
if (nla_put_be32(skb, NFQA_CT_INFO, htonl(tmp)))
|
||||
goto nla_put_failure;
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo, int diff)
|
||||
{
|
||||
struct nfq_ct_hook *nfq_ct;
|
||||
|
||||
nfq_ct = rcu_dereference(nfq_ct_hook);
|
||||
if (nfq_ct == NULL)
|
||||
return;
|
||||
|
||||
if ((ct->status & IPS_NAT_MASK) && diff)
|
||||
nfq_ct->seq_adjust(skb, ct, ctinfo, diff);
|
||||
}
|
Loading…
Reference in New Issue
Block a user