Florian Westphal says:

====================
netfilter: updates for net-next

The following patchset contains Netfilter updates for *net-next*.

1) Update nfnetlink_hook to dump the individual NAT type chains
instead of the nat base chains to userspace. From Phil Sutter.

2) Replace strlcpy/strlcat() with snprintf() in x_tables, from Ian Bridges.

3) Start replacing u_int8_t and u_int16t with u8 and u16 in netfilter.
From Carlos Grillet.

4) Replace strcpy() with strscpy() in netfilter, from David Laight.

5) Remove redundant NULL check before kvfree().

6) Add parameter validation to xt_tcpmss. Ensure mss_min <= mss_max and
invert <= 1.  From Feng Wu.

7) Add checkentry for xt_dscp 'tos' match. Implement tos_mt_check() to reject
invalid invert values.  Also from Feng Wu.

8) Stop hashing nf_conntrack_helper by tuple. Switch to hashing by name and
L4 protocol.

9) Remove tuples from conntrack helper definitions and port usage from
broadcast helpers. Add netlink policy validation to prevent protocol
number truncation.

10) Remove obsolete netfilter conntrack module parameters.

11) Bound num_counters in ebtables: do_replace() by MAX_EBT_ENTRIES to prevent
oversized vmalloc_array() allocations.  From Jiayuan Chen.

12) Make expectations created via nft_ct rules work with NAT.

netfilter pull request nf-next-26-07-02

* tag 'nf-next-26-07-02' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next:
  netfilter: nft_ct: support expectation creation for natted flows
  netfilter: ebtables: bound num_counters like nentries in do_replace()
  netfilter: conntrack: remove obsolete module parameters
  netfilter: conntrack: get rid of tuple in helper definitions
  netfilter: nf_conntrack_helper: do not hash by tuple
  netfilter: xt_dscp: add checkentry for tos match
  netfilter: xt_tcpmss: add checkentry for parameter validation
  netfilter: remove redundant null check before kvfree()
  netfilter: avoid strcpy usage
  netfilter: replace u_int8_t and u_int16t with u8 and u16
  netfilter: x_tables: replace strlcat() with snprintf()
  netfilter: nfnetlink_hook: Dump nat type chains
====================

Link: https://patch.msgid.link/20260702105003.13550-1-fw@strlen.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni
2026-07-03 22:00:23 +02:00
36 changed files with 246 additions and 260 deletions

View File

@@ -93,6 +93,7 @@ enum nf_hook_ops_type {
NF_HOOK_OP_NF_TABLES,
NF_HOOK_OP_BPF,
NF_HOOK_OP_NFT_FT,
NF_HOOK_OP_NAT,
};
struct nf_hook_ops {
@@ -140,6 +141,12 @@ struct nf_hook_entries {
*/
};
struct nf_nat_lookup_hook_priv {
struct nf_hook_entries __rcu *entries;
struct rcu_head rcu_head;
};
#ifdef CONFIG_NETFILTER
static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e)
{

View File

@@ -9,8 +9,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#include <uapi/linux/netfilter/nf_conntrack_tuple_common.h>
#define RAS_PORT 1719
#define Q931_PORT 1720
#define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */
/* This structure exists only once per master */

View File

@@ -50,8 +50,6 @@ struct nf_nat_pptp {
__be16 pac_call_id; /* NAT'ed PAC call id */
};
#define PPTP_CONTROL_PORT 1723
#define PPTP_PACKET_CONTROL 1
#define PPTP_PACKET_MGMT 2

View File

@@ -3,8 +3,6 @@
#define _NF_CONNTRACK_SANE_H
/* SANE tracking. */
#define SANE_PORT 6566
enum sane_state {
SANE_STATE_NORMAL,
SANE_STATE_START_REQUESTED,

View File

@@ -2,8 +2,6 @@
#ifndef _NF_CONNTRACK_TFTP_H
#define _NF_CONNTRACK_TFTP_H
#define TFTP_PORT 69
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/types.h>

View File

@@ -2123,7 +2123,7 @@ void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
int outin);
int ip_vs_confirm_conntrack(struct sk_buff *skb);
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
struct ip_vs_conn *cp, u_int8_t proto,
struct ip_vs_conn *cp, u8 proto,
const __be16 port, int from_rs);
void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);

View File

@@ -43,11 +43,10 @@ struct nf_conntrack_helper {
refcount_t ct_refcnt;
/* Tuple of things we will help (compared against server response) */
struct nf_conntrack_tuple tuple;
u8 nfproto; /* NFPROTO_*, can be NFPROTO_UNSPEC */
u8 l4proto; /* IPPROTO_UDP/TCP */
/* Function to call when data passes; return verdict, or -1 to
invalidate. */
/* Function to call when data passes; return verdict */
int __rcu (*help)(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info conntrackinfo);
@@ -94,8 +93,7 @@ struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
u16 l3num, u16 protonum, const char *name,
u16 default_port, u16 spec_port, u32 id,
u8 l3num, u16 protonum, const char *name,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
int (*help)(struct sk_buff *skb, unsigned int protoff,

View File

@@ -39,6 +39,8 @@
#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
COUNTER_OFFSET(n) * cpu))
#define MAX_EBT_ENTRIES (((INT_MAX - sizeof(struct ebt_table_info)) / \
NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
struct ebt_pernet {
struct list_head tables;
@@ -1124,10 +1126,9 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
return -EINVAL;
/* overflow check */
if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) /
NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
if (tmp.nentries >= MAX_EBT_ENTRIES)
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
if (tmp.num_counters >= MAX_EBT_ENTRIES)
return -ENOMEM;
tmp.name[sizeof(tmp.name) - 1] = 0;
@@ -2265,10 +2266,9 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
if (tmp.entries_size == 0)
return -EINVAL;
if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) /
NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
if (tmp.nentries >= MAX_EBT_ENTRIES)
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
if (tmp.num_counters >= MAX_EBT_ENTRIES)
return -ENOMEM;
memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));

View File

@@ -213,7 +213,7 @@ static int __init nf_nat_snmp_basic_init(void)
RCU_INIT_POINTER(nf_nat_snmp_hook, help);
nf_ct_helper_init(&snmp_trap_helper, AF_INET, IPPROTO_UDP,
"snmp_trap", SNMP_TRAP_PORT, SNMP_TRAP_PORT, SNMP_TRAP_PORT,
"snmp_trap",
&snmp_exp_policy, 0, help, NULL, THIS_MODULE);
err = nf_conntrack_helper_register(&snmp_trap_helper, &snmp_trap_helper_ptr);

View File

@@ -208,7 +208,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
* Use port 0 to expect connection from any port.
*/
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
struct ip_vs_conn *cp, u_int8_t proto,
struct ip_vs_conn *cp, u8 proto,
const __be16 port, int from_rs)
{
struct nf_conntrack_expect *exp;

View File

@@ -89,7 +89,7 @@ static int amanda_help(struct sk_buff *skb,
struct nf_conntrack_tuple *tuple;
unsigned int dataoff, start, stop, off, i;
char pbuf[sizeof("65535")], *tmp;
u_int16_t len;
u16 len;
__be16 port;
int ret = NF_ACCEPT;
nf_nat_amanda_hook_fn *nf_nat_amanda;
@@ -199,10 +199,10 @@ static int __init nf_conntrack_amanda_init(void)
}
nf_ct_helper_init(&amanda_helper[0], AF_INET, IPPROTO_UDP,
HELPER_NAME, 10080, 10080, 10080,
HELPER_NAME,
&amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);
nf_ct_helper_init(&amanda_helper[1], AF_INET6, IPPROTO_UDP,
HELPER_NAME, 10080, 10080, 10080,
HELPER_NAME,
&amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);
ret = nf_conntrack_helpers_register(amanda_helper,

View File

@@ -66,8 +66,6 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
helper = rcu_dereference(help->helper);
if (helper)
exp->tuple.src.u.udp.port = helper->tuple.src.u.udp.port;
exp->mask.src.u3.ip = mask;
exp->mask.src.u.udp.port = htons(0xFFFF);

View File

@@ -35,11 +35,6 @@ MODULE_ALIAS("ip_conntrack_ftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
static DEFINE_SPINLOCK(nf_ftp_lock);
#define MAX_PORTS 8
static u_int16_t ports[MAX_PORTS];
static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
static bool loose;
module_param(loose, bool, 0600);
@@ -560,8 +555,8 @@ static int nf_ct_ftp_from_nlattr(struct nlattr *attr, struct nf_conn *ct)
return 0;
}
static struct nf_conntrack_helper ftp[MAX_PORTS * 2] __read_mostly;
static struct nf_conntrack_helper *ftp_ptr[MAX_PORTS * 2] __read_mostly;
static struct nf_conntrack_helper ftp __read_mostly;
static struct nf_conntrack_helper *ftp_ptr __read_mostly;
static const struct nf_conntrack_expect_policy ftp_exp_policy = {
.max_expected = 1,
@@ -570,32 +565,23 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = {
static void __exit nf_conntrack_ftp_fini(void)
{
nf_conntrack_helpers_unregister(ftp_ptr, ports_c * 2);
nf_conntrack_helper_unregister(ftp_ptr);
}
static int __init nf_conntrack_ftp_init(void)
{
int i, ret = 0;
int ret = 0;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_ftp_master));
if (ports_c == 0)
ports[ports_c++] = FTP_PORT;
/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
are tracked or not - YK */
for (i = 0; i < ports_c; i++) {
nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP,
HELPER_NAME, FTP_PORT, ports[i], ports[i],
&ftp_exp_policy, 0, help,
nf_ct_ftp_from_nlattr, THIS_MODULE);
nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP,
HELPER_NAME, FTP_PORT, ports[i], ports[i],
&ftp_exp_policy, 0, help,
nf_ct_ftp_from_nlattr, THIS_MODULE);
}
nf_ct_helper_init(&ftp, NFPROTO_UNSPEC, IPPROTO_TCP,
HELPER_NAME,
&ftp_exp_policy, 0, help,
nf_ct_ftp_from_nlattr, THIS_MODULE);
ret = nf_conntrack_helpers_register(ftp, ports_c * 2, ftp_ptr);
ret = nf_conntrack_helper_register(&ftp, &ftp_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;

View File

@@ -671,7 +671,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
static int callforward_do_filter(struct net *net,
const union nf_inet_addr *src,
const union nf_inet_addr *dst,
u_int8_t family)
u8 family)
{
int ret = 0;
@@ -1713,19 +1713,19 @@ static int __init h323_helper_init(void)
int ret;
nf_ct_helper_init(&nf_conntrack_helper_ras[0], AF_INET, IPPROTO_UDP,
"RAS", RAS_PORT, RAS_PORT, RAS_PORT,
"RAS",
&ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_ras[1], AF_INET6, IPPROTO_UDP,
"RAS", RAS_PORT, RAS_PORT, RAS_PORT,
"RAS",
&ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_h245, AF_UNSPEC, IPPROTO_UDP,
"H.245", 0, 0, 0,
"H.245",
&h245_exp_policy, 0, h245_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_q931[0], AF_INET, IPPROTO_TCP,
"Q.931", Q931_PORT, Q931_PORT, Q931_PORT,
"Q.931",
&q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_q931[1], AF_INET6, IPPROTO_TCP,
"Q.931", Q931_PORT, Q931_PORT, Q931_PORT,
"Q.931",
&q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);
ret = nf_conntrack_helper_register(&nf_conntrack_helper_h245,

View File

@@ -40,12 +40,16 @@ static unsigned int nf_ct_helper_count __read_mostly;
static DEFINE_MUTEX(nf_ct_nat_helpers_mutex);
static struct list_head nf_ct_nat_helpers __read_mostly;
/* Stupid hash, but collision free for the default registrations of the
* helpers currently in the kernel. */
static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
static unsigned int helper_hash(const char *name, u8 protonum)
{
return (((tuple->src.l3num << 8) | tuple->dst.protonum) ^
(__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
static u32 seed;
u32 initval;
get_random_once(&seed, sizeof(seed));
initval = seed ^ protonum;
return jhash(name, strlen(name), initval) % nf_ct_helper_hsize;
}
struct nf_conntrack_helper *
@@ -54,18 +58,18 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)
struct nf_conntrack_helper *h;
unsigned int i;
for (i = 0; i < nf_ct_helper_hsize; i++) {
hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
if (strcmp(h->name, name))
continue;
if (!nf_ct_helper_hash)
return NULL;
if (h->tuple.src.l3num != NFPROTO_UNSPEC &&
h->tuple.src.l3num != l3num)
continue;
i = helper_hash(name, protonum);
if (h->tuple.dst.protonum == protonum)
return h;
}
hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
if (strcmp(h->name, name))
continue;
if (h->nfproto != NFPROTO_UNSPEC && h->nfproto != l3num)
continue;
if (h->l4proto == protonum)
return h;
}
return NULL;
}
@@ -363,9 +367,8 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_log);
int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
{
struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
unsigned int h = helper_hash(&me->tuple);
struct nf_conntrack_helper *cur;
unsigned int h;
int ret = 0, i;
BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
@@ -382,29 +385,18 @@ int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
return -EINVAL;
}
h = helper_hash(me->name, me->l4proto);
mutex_lock(&nf_ct_helper_mutex);
for (i = 0; i < nf_ct_helper_hsize; i++) {
hlist_for_each_entry(cur, &nf_ct_helper_hash[i], hnode) {
if (!strcmp(cur->name, me->name) &&
(cur->tuple.src.l3num == NFPROTO_UNSPEC ||
cur->tuple.src.l3num == me->tuple.src.l3num) &&
cur->tuple.dst.protonum == me->tuple.dst.protonum) {
ret = -EBUSY;
goto out;
}
hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
if (!strcmp(cur->name, me->name) &&
(cur->nfproto == NFPROTO_UNSPEC ||
cur->nfproto == me->nfproto) &&
cur->l4proto == me->l4proto) {
ret = -EBUSY;
goto out;
}
}
/* avoid unpredictable behaviour for auto_assign_helper */
if (!(me->flags & NF_CT_HELPER_F_USERSPACE)) {
hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple,
&mask)) {
ret = -EBUSY;
goto out;
}
}
}
refcount_set(&me->ct_refcnt, 1);
hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
nf_ct_helper_count++;
@@ -479,8 +471,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
u16 l3num, u16 protonum, const char *name,
u16 default_port, u16 spec_port, u32 id,
u8 l3num, u16 protonum, const char *name,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
int (*help)(struct sk_buff *skb, unsigned int protoff,
@@ -492,9 +483,8 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,
{
memset(helper, 0, sizeof(*helper));
helper->tuple.src.l3num = l3num;
helper->tuple.dst.protonum = protonum;
helper->tuple.src.u.all = htons(spec_port);
helper->nfproto = l3num;
helper->l4proto = protonum;
rcu_assign_pointer(helper->help, help);
helper->from_nlattr = from_nlattr;
@@ -502,10 +492,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,
snprintf(helper->nat_mod_name, sizeof(helper->nat_mod_name),
NF_NAT_HELPER_PREFIX "%s", name);
if (spec_port == default_port)
snprintf(helper->name, sizeof(helper->name), "%s", name);
else
snprintf(helper->name, sizeof(helper->name), "%s-%u", name, id);
snprintf(helper->name, sizeof(helper->name), "%s", name);
if (WARN_ON_ONCE(expect_class_max >= NF_CT_MAX_EXPECT_CLASSES))
return;

View File

@@ -21,9 +21,6 @@
#include <net/netfilter/nf_conntrack_helper.h>
#include <linux/netfilter/nf_conntrack_irc.h>
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
static unsigned int ports_c;
static unsigned int max_dcc_channels = 8;
static unsigned int dcc_timeout __read_mostly = 300;
/* This is slow, but it's simple. --RR */
@@ -42,8 +39,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_conntrack_irc");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
module_param(max_dcc_channels, uint, 0400);
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per "
"IRC session");
@@ -254,13 +249,13 @@ static int help(struct sk_buff *skb, unsigned int protoff,
return ret;
}
static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly;
static struct nf_conntrack_helper *irc_ptr[MAX_PORTS] __read_mostly;
static struct nf_conntrack_helper irc __read_mostly;
static struct nf_conntrack_helper *irc_ptr __read_mostly;
static struct nf_conntrack_expect_policy irc_exp_policy;
static int __init nf_conntrack_irc_init(void)
{
int i, ret;
int ret;
nf_conntrack_helper_deprecated(HELPER_NAME);
@@ -282,17 +277,11 @@ static int __init nf_conntrack_irc_init(void)
if (!irc_buffer)
return -ENOMEM;
/* If no port given, default to standard irc port */
if (ports_c == 0)
ports[ports_c++] = IRC_PORT;
nf_ct_helper_init(&irc, AF_INET, IPPROTO_TCP, HELPER_NAME,
&irc_exp_policy,
0, help, NULL, THIS_MODULE);
for (i = 0; i < ports_c; i++) {
nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, HELPER_NAME,
IRC_PORT, ports[i], i, &irc_exp_policy,
0, help, NULL, THIS_MODULE);
}
ret = nf_conntrack_helpers_register(&irc[0], ports_c, irc_ptr);
ret = nf_conntrack_helper_register(&irc, &irc_ptr);
if (ret) {
pr_err("failed to register helpers\n");
kfree(irc_buffer);
@@ -304,7 +293,7 @@ static int __init nf_conntrack_irc_init(void)
static void __exit nf_conntrack_irc_fini(void)
{
nf_conntrack_helpers_unregister(irc_ptr, ports_c);
nf_conntrack_helper_unregister(irc_ptr);
kfree(irc_buffer);
}

View File

@@ -21,7 +21,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#define HELPER_NAME "netbios-ns"
#define NMBD_PORT 137
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
@@ -54,7 +53,6 @@ static int __init nf_conntrack_netbios_ns_init(void)
exp_policy.timeout = timeout;
nf_ct_helper_init(&helper, AF_INET, IPPROTO_UDP, HELPER_NAME,
NMBD_PORT, NMBD_PORT, NMBD_PORT,
&exp_policy, 0, netbios_ns_help, NULL, THIS_MODULE);
return nf_conntrack_helper_register(&helper, &helper_ptr);

View File

@@ -31,8 +31,8 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
if (!helper)
return NF_ACCEPT;
if (helper->tuple.src.l3num != NFPROTO_UNSPEC &&
helper->tuple.src.l3num != proto)
if (helper->nfproto != NFPROTO_UNSPEC &&
helper->nfproto != proto)
return NF_ACCEPT;
switch (proto) {
@@ -60,7 +60,7 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
return NF_DROP;
}
if (helper->tuple.dst.protonum != proto)
if (helper->l4proto != proto)
return NF_ACCEPT;
helper_cb = rcu_dereference(helper->help);

View File

@@ -540,7 +540,7 @@ static int __init nf_conntrack_pptp_init(void)
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_pptp_master));
nf_ct_helper_init(&pptp, AF_INET, IPPROTO_TCP,
"pptp", PPTP_CONTROL_PORT, PPTP_CONTROL_PORT, PPTP_CONTROL_PORT,
"pptp",
&pptp_exp_policy, 0, conntrack_pptp_help, NULL, THIS_MODULE);
pptp.destroy = gre_pptp_destroy_siblings;

View File

@@ -34,11 +34,6 @@ MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>");
MODULE_DESCRIPTION("SANE connection tracking helper");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
#define MAX_PORTS 8
static u_int16_t ports[MAX_PORTS];
static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
struct sane_request {
__be32 RPC_code;
#define SANE_NET_START 7 /* RPC code */
@@ -169,8 +164,8 @@ static int help(struct sk_buff *skb,
return ret;
}
static struct nf_conntrack_helper sane[MAX_PORTS * 2] __read_mostly;
static struct nf_conntrack_helper *sane_ptr[MAX_PORTS * 2] __read_mostly;
static struct nf_conntrack_helper sane __read_mostly;
static struct nf_conntrack_helper *sane_ptr __read_mostly;
static const struct nf_conntrack_expect_policy sane_exp_policy = {
.max_expected = 1,
@@ -179,32 +174,21 @@ static const struct nf_conntrack_expect_policy sane_exp_policy = {
static void __exit nf_conntrack_sane_fini(void)
{
nf_conntrack_helpers_unregister(sane_ptr, ports_c * 2);
nf_conntrack_helper_unregister(sane_ptr);
}
static int __init nf_conntrack_sane_init(void)
{
int i, ret = 0;
int ret = 0;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sane_master));
if (ports_c == 0)
ports[ports_c++] = SANE_PORT;
nf_ct_helper_init(&sane, NFPROTO_UNSPEC, IPPROTO_TCP,
HELPER_NAME,
&sane_exp_policy, 0, help, NULL,
THIS_MODULE);
/* FIXME should be configurable whether IPv4 and IPv6 connections
are tracked or not - YK */
for (i = 0; i < ports_c; i++) {
nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP,
HELPER_NAME, SANE_PORT, ports[i], ports[i],
&sane_exp_policy, 0, help, NULL,
THIS_MODULE);
nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP,
HELPER_NAME, SANE_PORT, ports[i], ports[i],
&sane_exp_policy, 0, help, NULL,
THIS_MODULE);
}
ret = nf_conntrack_helpers_register(sane, ports_c * 2, sane_ptr);
ret = nf_conntrack_helper_register(&sane, &sane_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;

View File

@@ -35,12 +35,6 @@ MODULE_DESCRIPTION("SIP connection tracking helper");
MODULE_ALIAS("ip_conntrack_sip");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of SIP servers");
static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
module_param(sip_timeout, uint, 0600);
MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
@@ -1767,8 +1761,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
return process_sip_msg(skb, ct, protoff, dataoff, &dptr, &datalen);
}
static struct nf_conntrack_helper sip[MAX_PORTS * 4] __read_mostly;
static struct nf_conntrack_helper *sip_ptr[MAX_PORTS * 4] __read_mostly;
static struct nf_conntrack_helper sip[2] __read_mostly;
static struct nf_conntrack_helper *sip_ptr[2] __read_mostly;
static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
[SIP_EXPECT_SIGNALLING] = {
@@ -1795,38 +1789,25 @@ static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1
static void __exit nf_conntrack_sip_fini(void)
{
nf_conntrack_helpers_unregister(sip_ptr, ports_c * 4);
nf_conntrack_helpers_unregister(sip_ptr, 2);
}
static int __init nf_conntrack_sip_init(void)
{
int i, ret;
int ret;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sip_master));
if (ports_c == 0)
ports[ports_c++] = SIP_PORT;
nf_ct_helper_init(&sip[0], NFPROTO_UNSPEC, IPPROTO_UDP,
HELPER_NAME,
sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
NULL, THIS_MODULE);
nf_ct_helper_init(&sip[1], NFPROTO_UNSPEC, IPPROTO_TCP,
HELPER_NAME,
sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
NULL, THIS_MODULE);
for (i = 0; i < ports_c; i++) {
nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP,
HELPER_NAME, SIP_PORT, ports[i], i,
sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
NULL, THIS_MODULE);
nf_ct_helper_init(&sip[4 * i + 1], AF_INET, IPPROTO_TCP,
HELPER_NAME, SIP_PORT, ports[i], i,
sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
NULL, THIS_MODULE);
nf_ct_helper_init(&sip[4 * i + 2], AF_INET6, IPPROTO_UDP,
HELPER_NAME, SIP_PORT, ports[i], i,
sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
NULL, THIS_MODULE);
nf_ct_helper_init(&sip[4 * i + 3], AF_INET6, IPPROTO_TCP,
HELPER_NAME, SIP_PORT, ports[i], i,
sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
NULL, THIS_MODULE);
}
ret = nf_conntrack_helpers_register(sip, ports_c * 4, sip_ptr);
ret = nf_conntrack_helpers_register(sip, 2, sip_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;

View File

@@ -14,8 +14,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#include <linux/netfilter/nf_conntrack_snmp.h>
#define SNMP_PORT 161
MODULE_AUTHOR("Jiri Olsa <jolsa@redhat.com>");
MODULE_DESCRIPTION("SNMP service broadcast connection tracking helper");
MODULE_LICENSE("GPL");
@@ -55,7 +53,7 @@ static int __init nf_conntrack_snmp_init(void)
exp_policy.timeout = timeout;
nf_ct_helper_init(&helper, AF_INET, IPPROTO_UDP,
"snmp", SNMP_PORT, SNMP_PORT, SNMP_PORT,
"snmp",
&exp_policy, 0, snmp_conntrack_help, NULL,
THIS_MODULE);

View File

@@ -26,12 +26,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_conntrack_tftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
nf_nat_tftp_hook_fn __rcu *nf_nat_tftp_hook __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);
@@ -95,8 +89,8 @@ static int tftp_help(struct sk_buff *skb,
return ret;
}
static struct nf_conntrack_helper tftp[MAX_PORTS * 2] __read_mostly;
static struct nf_conntrack_helper *tftp_ptr[MAX_PORTS * 2] __read_mostly;
static struct nf_conntrack_helper tftp __read_mostly;
static struct nf_conntrack_helper *tftp_ptr __read_mostly;
static const struct nf_conntrack_expect_policy tftp_exp_policy = {
.max_expected = 1,
@@ -105,30 +99,21 @@ static const struct nf_conntrack_expect_policy tftp_exp_policy = {
static void __exit nf_conntrack_tftp_fini(void)
{
nf_conntrack_helpers_unregister(tftp_ptr, ports_c * 2);
nf_conntrack_helper_unregister(tftp_ptr);
}
static int __init nf_conntrack_tftp_init(void)
{
int i, ret;
int ret;
NF_CT_HELPER_BUILD_BUG_ON(0);
if (ports_c == 0)
ports[ports_c++] = TFTP_PORT;
nf_ct_helper_init(&tftp, NFPROTO_UNSPEC, IPPROTO_UDP,
HELPER_NAME,
&tftp_exp_policy, 0, tftp_help, NULL,
THIS_MODULE);
for (i = 0; i < ports_c; i++) {
nf_ct_helper_init(&tftp[2 * i], AF_INET, IPPROTO_UDP,
HELPER_NAME, TFTP_PORT, ports[i], i,
&tftp_exp_policy, 0, tftp_help, NULL,
THIS_MODULE);
nf_ct_helper_init(&tftp[2 * i + 1], AF_INET6, IPPROTO_UDP,
HELPER_NAME, TFTP_PORT, ports[i], i,
&tftp_exp_policy, 0, tftp_help, NULL,
THIS_MODULE);
}
ret = nf_conntrack_helpers_register(tftp, ports_c * 2, tftp_ptr);
ret = nf_conntrack_helper_register(&tftp, &tftp_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;

View File

@@ -39,12 +39,6 @@ static struct hlist_head *nf_nat_bysource __read_mostly;
static unsigned int nf_nat_htable_size __read_mostly;
static siphash_aligned_key_t nf_nat_hash_rnd;
struct nf_nat_lookup_hook_priv {
struct nf_hook_entries __rcu *entries;
struct rcu_head rcu_head;
};
struct nf_nat_hooks_net {
struct nf_hook_ops *nat_hook_ops;
unsigned int users;

View File

@@ -770,6 +770,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_NAT_DST,
.hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -777,6 +778,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_NAT_SRC,
.hook_ops_type = NF_HOOK_OP_NAT,
},
/* Before packet filtering, change destination */
{
@@ -784,6 +786,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST,
.hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -791,6 +794,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC,
.hook_ops_type = NF_HOOK_OP_NAT,
},
};
@@ -1031,6 +1035,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_NAT_DST,
.hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -1038,6 +1043,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_NAT_SRC,
.hook_ops_type = NF_HOOK_OP_NAT,
},
/* Before packet filtering, change destination */
{
@@ -1045,6 +1051,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_NAT_DST,
.hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -1052,6 +1059,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_NAT_SRC,
.hook_ops_type = NF_HOOK_OP_NAT,
},
};

View File

@@ -67,7 +67,7 @@ nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,
}
static const struct nla_policy nfnl_cthelper_tuple_pol[NFCTH_TUPLE_MAX+1] = {
[NFCTH_TUPLE_L3PROTONUM] = { .type = NLA_U16, },
[NFCTH_TUPLE_L3PROTONUM] = NLA_POLICY_MAX(NLA_BE16, NFPROTO_IPV6),
[NFCTH_TUPLE_L4PROTONUM] = { .type = NLA_U8, },
};
@@ -256,7 +256,8 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
helper->data_len = size;
helper->flags |= NF_CT_HELPER_F_USERSPACE;
memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple));
helper->nfproto = tuple->src.l3num;
helper->l4proto = tuple->dst.protonum;
helper->me = THIS_MODULE;
helper->help = nfnl_userspace_cthelper;
@@ -451,8 +452,8 @@ static int nfnl_cthelper_new(struct sk_buff *skb, const struct nfnl_info *info,
if (strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
continue;
if ((tuple.src.l3num != cur->tuple.src.l3num ||
tuple.dst.protonum != cur->tuple.dst.protonum))
if ((tuple.src.l3num != cur->nfproto ||
tuple.dst.protonum != cur->l4proto))
continue;
if (info->nlh->nlmsg_flags & NLM_F_EXCL)
@@ -481,10 +482,10 @@ nfnl_cthelper_dump_tuple(struct sk_buff *skb,
goto nla_put_failure;
if (nla_put_be16(skb, NFCTH_TUPLE_L3PROTONUM,
htons(helper->tuple.src.l3num)))
htons(helper->nfproto)))
goto nla_put_failure;
if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->tuple.dst.protonum))
if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->l4proto))
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
@@ -663,8 +664,8 @@ static int nfnl_cthelper_get(struct sk_buff *skb, const struct nfnl_info *info,
continue;
if (tuple_set &&
(tuple.src.l3num != cur->tuple.src.l3num ||
tuple.dst.protonum != cur->tuple.dst.protonum))
(tuple.src.l3num != cur->nfproto ||
tuple.dst.protonum != cur->l4proto))
continue;
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -723,8 +724,8 @@ static int nfnl_cthelper_del(struct sk_buff *skb, const struct nfnl_info *info,
continue;
if (tuple_set &&
(tuple.src.l3num != cur->tuple.src.l3num ||
tuple.dst.protonum != cur->tuple.dst.protonum))
(tuple.src.l3num != cur->nfproto ||
tuple.dst.protonum != cur->l4proto))
continue;
found = true;

View File

@@ -168,7 +168,7 @@ static int cttimeout_new_timeout(struct sk_buff *skb,
if (ret < 0)
goto err_free_timeout_policy;
strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
nla_strscpy(timeout->name, cda[CTA_TIMEOUT_NAME], sizeof(timeout->name));
timeout->timeout->l3num = l3num;
timeout->timeout->l4proto = l4proto;
refcount_set(&timeout->timeout->refcnt, 1);

View File

@@ -190,7 +190,7 @@ static int nfnl_hook_put_nft_ft_info(struct sk_buff *nlskb,
static int nfnl_hook_dump_one(struct sk_buff *nlskb,
const struct nfnl_dump_hook_data *ctx,
const struct nf_hook_ops *ops,
const struct nf_hook_ops *ops, int priority,
int family, unsigned int seq)
{
u16 event = nfnl_msg_type(NFNL_SUBSYS_HOOK, NFNL_MSG_HOOK_GET);
@@ -244,7 +244,7 @@ static int nfnl_hook_dump_one(struct sk_buff *nlskb,
if (ret)
goto nla_put_failure;
ret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(ops->priority));
ret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(priority));
if (ret)
goto nla_put_failure;
@@ -337,6 +337,30 @@ nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *de
return hook_head;
}
static int nfnl_hook_dump_nat(struct sk_buff *nlskb,
const struct nfnl_dump_hook_data *ctx,
const struct nf_hook_ops *ops,
int family, unsigned int seq)
{
struct nf_nat_lookup_hook_priv *priv = ops->priv;
struct nf_hook_entries *e = rcu_dereference(priv->entries);
struct nf_hook_ops **nat_ops;
int i, err;
if (!e)
return 0;
nat_ops = nf_hook_entries_get_hook_ops(e);
for (i = 0; i < e->num_hook_entries; i++) {
err = nfnl_hook_dump_one(nlskb, ctx, nat_ops[i],
ops->priority, family, seq);
if (err)
return err;
}
return 0;
}
static int nfnl_hook_dump(struct sk_buff *nlskb,
struct netlink_callback *cb)
{
@@ -365,8 +389,13 @@ static int nfnl_hook_dump(struct sk_buff *nlskb,
ops = nf_hook_entries_get_hook_ops(e);
for (; i < e->num_hook_entries; i++) {
err = nfnl_hook_dump_one(nlskb, ctx, ops[i], family,
cb->nlh->nlmsg_seq);
if (ops[i]->hook_ops_type == NF_HOOK_OP_NAT)
err = nfnl_hook_dump_nat(nlskb, ctx, ops[i], family,
cb->nlh->nlmsg_seq);
else
err = nfnl_hook_dump_one(nlskb, ctx, ops[i],
ops[i]->priority, family,
cb->nlh->nlmsg_seq);
if (err)
break;
}

View File

@@ -1297,6 +1297,17 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb,
return 0;
}
#if IS_ENABLED(CONFIG_NF_NAT)
static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)
{
const struct nf_ct_helper_expectfn *expfn;
expfn = nf_ct_helper_expectfn_find_by_name("nat-follow-master");
if (expfn)
expfn->expectfn(ct, this);
}
#endif
static void nft_ct_expect_obj_eval(struct nft_object *obj,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
@@ -1342,6 +1353,13 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,
priv->l4proto, NULL, &priv->dport);
exp->timeout += priv->timeout;
#if IS_ENABLED(CONFIG_NF_NAT)
if (ct->status & IPS_NAT_MASK) {
exp->saved_proto.tcp.port = priv->dport;
exp->dir = !dir;
exp->expectfn = nft_ct_nat_follow_master;
}
#endif
if (nf_ct_expect_related(exp, 0) != 0)
regs->verdict.code = NF_DROP;
@@ -1375,6 +1393,13 @@ static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
.owner = THIS_MODULE,
};
#if IS_ENABLED(CONFIG_NF_NAT)
static struct nf_ct_helper_expectfn nft_ct_nat __read_mostly = {
.name = "nft_ct-follow-master",
.expectfn = nft_ct_nat_follow_master,
};
#endif
static int __init nft_ct_module_init(void)
{
int err;
@@ -1400,6 +1425,9 @@ static int __init nft_ct_module_init(void)
err = nft_register_obj(&nft_ct_timeout_obj_type);
if (err < 0)
goto err4;
#endif
#if IS_ENABLED(CONFIG_NF_NAT)
nf_ct_helper_expectfn_register(&nft_ct_nat);
#endif
return 0;
@@ -1425,6 +1453,13 @@ static void __exit nft_ct_module_exit(void)
nft_unregister_obj(&nft_ct_helper_obj_type);
nft_unregister_expr(&nft_notrack_type);
nft_unregister_expr(&nft_ct_type);
#if IS_ENABLED(CONFIG_NF_NAT)
nf_ct_helper_expectfn_unregister(&nft_ct_nat);
synchronize_rcu();
nf_ct_helper_expectfn_destroy(&nft_ct_nat);
synchronize_rcu();
#endif
}
module_init(nft_ct_module_init);

View File

@@ -544,8 +544,7 @@ static int nft_array_intervals_alloc(struct nft_array *array, u32 max_intervals)
if (!intervals)
return -ENOMEM;
if (array->intervals)
kvfree(array->intervals);
kvfree(array->intervals);
array->intervals = intervals;
array->max_intervals = max_intervals;

View File

@@ -1920,9 +1920,9 @@ static const struct seq_operations xt_target_seq_ops = {
.show = xt_target_seq_show,
};
#define FORMAT_TABLES "_tables_names"
#define FORMAT_MATCHES "_tables_matches"
#define FORMAT_TARGETS "_tables_targets"
#define FORMAT_TABLES "%s_tables_names"
#define FORMAT_MATCHES "%s_tables_matches"
#define FORMAT_TARGETS "%s_tables_targets"
#endif /* CONFIG_PROC_FS */
@@ -2033,8 +2033,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
root_uid = make_kuid(net->user_ns, 0);
root_gid = make_kgid(net->user_ns, 0);
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
proc = proc_create_net_data(buf, 0440, net->proc_net, &xt_table_seq_ops,
sizeof(struct seq_net_private),
(void *)(unsigned long)af);
@@ -2043,8 +2042,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
if (uid_valid(root_uid) && gid_valid(root_gid))
proc_set_user(proc, root_uid, root_gid);
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
proc = proc_create_seq_private(buf, 0440, net->proc_net,
&xt_match_seq_ops, sizeof(struct nf_mttg_trav),
(void *)(unsigned long)af);
@@ -2053,8 +2051,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
if (uid_valid(root_uid) && gid_valid(root_gid))
proc_set_user(proc, root_uid, root_gid);
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);
proc = proc_create_seq_private(buf, 0440, net->proc_net,
&xt_target_seq_ops, sizeof(struct nf_mttg_trav),
(void *)(unsigned long)af);
@@ -2068,13 +2065,11 @@ int xt_proto_init(struct net *net, u_int8_t af)
#ifdef CONFIG_PROC_FS
out_remove_matches:
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
out_remove_tables:
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
out:
return -1;
@@ -2087,16 +2082,13 @@ void xt_proto_fini(struct net *net, u_int8_t af)
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
strscpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
#endif /*CONFIG_PROC_FS*/
}

View File

@@ -16,7 +16,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_TCPOPTSTRIP.h>
static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
static inline unsigned int optlen(const u8 *opt, unsigned int offset)
{
/* Beware zero-length options: make finite progress */
if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
@@ -33,8 +33,8 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
const struct xt_tcpoptstrip_target_info *info = par->targinfo;
struct tcphdr *tcph, _th;
unsigned int optl, i, j;
u_int16_t n, o;
u_int8_t *opt;
u16 n, o;
u8 *opt;
int tcp_hdrlen;
/* This is a fragment, no TCP header is available */
@@ -97,7 +97,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
{
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
int tcphoff;
u_int8_t nexthdr;
u8 nexthdr;
__be16 frag_off;
nexthdr = ipv6h->nexthdr;

View File

@@ -49,6 +49,16 @@ static int dscp_mt_check(const struct xt_mtchk_param *par)
return 0;
}
static int tos_mt_check(const struct xt_mtchk_param *par)
{
const struct xt_tos_match_info *info = par->matchinfo;
if (info->invert > 1)
return -EINVAL;
return 0;
}
static bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_tos_match_info *info = par->matchinfo;
@@ -82,6 +92,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
.name = "tos",
.revision = 1,
.family = NFPROTO_IPV4,
.checkentry = tos_mt_check,
.match = tos_mt,
.matchsize = sizeof(struct xt_tos_match_info),
.me = THIS_MODULE,
@@ -90,6 +101,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
.name = "tos",
.revision = 1,
.family = NFPROTO_IPV6,
.checkentry = tos_mt_check,
.match = tos_mt,
.matchsize = sizeof(struct xt_tos_match_info),
.me = THIS_MODULE,

View File

@@ -400,7 +400,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
t->nstamps_max_mask = nstamp_mask;
memcpy(&t->mask, &info->mask, sizeof(t->mask));
strcpy(t->name, info->name);
strscpy(t->name, info->name);
INIT_LIST_HEAD(&t->lru_list);
for (i = 0; i < ip_list_hash_size; i++)
INIT_LIST_HEAD(&t->iphash[i]);

View File

@@ -78,10 +78,23 @@ tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)
return false;
}
static int tcpmss_mt_check(const struct xt_mtchk_param *par)
{
const struct xt_tcpmss_match_info *info = par->matchinfo;
if (info->mss_min > info->mss_max)
return -EINVAL;
if (info->invert > 1)
return -EINVAL;
return 0;
}
static struct xt_match tcpmss_mt_reg[] __read_mostly = {
{
.name = "tcpmss",
.family = NFPROTO_IPV4,
.checkentry = tcpmss_mt_check,
.match = tcpmss_mt,
.matchsize = sizeof(struct xt_tcpmss_match_info),
.proto = IPPROTO_TCP,

View File

@@ -1527,8 +1527,8 @@ static int tcf_ct_dump_helper(struct sk_buff *skb,
return 0;
if (nla_put_string(skb, TCA_CT_HELPER_NAME, helper->name) ||
nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper->tuple.src.l3num) ||
nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper->tuple.dst.protonum))
nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper->nfproto) ||
nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper->l4proto))
return -1;
return 0;