Commit 4b7326a3 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Revert "netfilter: xt_recent: relax ip_pkt_list_tot restrictions"

This reverts commit abc86d0f as it is
broken in 3.19 and is easier to revert here than try to fix it.

Reported-by: Florian Westphal <fw@strlen.de
Reported-by: default avatarDavid Miller <davem@redhat.com>
Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
parent 1181ed21
...@@ -43,29 +43,25 @@ MODULE_LICENSE("GPL"); ...@@ -43,29 +43,25 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_recent"); MODULE_ALIAS("ipt_recent");
MODULE_ALIAS("ip6t_recent"); MODULE_ALIAS("ip6t_recent");
static unsigned int ip_list_tot __read_mostly = 100; static unsigned int ip_list_tot = 100;
static unsigned int ip_list_hash_size __read_mostly; static unsigned int ip_pkt_list_tot = 20;
static unsigned int ip_list_perms __read_mostly = 0644; static unsigned int ip_list_hash_size = 0;
static unsigned int ip_list_uid __read_mostly; static unsigned int ip_list_perms = 0644;
static unsigned int ip_list_gid __read_mostly; static unsigned int ip_list_uid = 0;
static unsigned int ip_list_gid = 0;
module_param(ip_list_tot, uint, 0400); module_param(ip_list_tot, uint, 0400);
module_param(ip_pkt_list_tot, uint, 0400);
module_param(ip_list_hash_size, uint, 0400); module_param(ip_list_hash_size, uint, 0400);
module_param(ip_list_perms, uint, 0400); module_param(ip_list_perms, uint, 0400);
module_param(ip_list_uid, uint, S_IRUGO | S_IWUSR); module_param(ip_list_uid, uint, S_IRUGO | S_IWUSR);
module_param(ip_list_gid, uint, S_IRUGO | S_IWUSR); module_param(ip_list_gid, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list");
MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP address to remember (max. 255)");
MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs");
MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files"); MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files");
MODULE_PARM_DESC(ip_list_uid, "default owner of /proc/net/xt_recent/* files"); MODULE_PARM_DESC(ip_list_uid, "default owner of /proc/net/xt_recent/* files");
MODULE_PARM_DESC(ip_list_gid, "default owning group of /proc/net/xt_recent/* files"); MODULE_PARM_DESC(ip_list_gid, "default owning group of /proc/net/xt_recent/* files");
/* retained for backwards compatibility */
static unsigned int ip_pkt_list_tot __read_mostly;
module_param(ip_pkt_list_tot, uint, 0400);
MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP address to remember (max. 255)");
#define XT_RECENT_MAX_NSTAMPS 256
struct recent_entry { struct recent_entry {
struct list_head list; struct list_head list;
struct list_head lru_list; struct list_head lru_list;
...@@ -83,7 +79,6 @@ struct recent_table { ...@@ -83,7 +79,6 @@ struct recent_table {
union nf_inet_addr mask; union nf_inet_addr mask;
unsigned int refcnt; unsigned int refcnt;
unsigned int entries; unsigned int entries;
u8 nstamps_max_mask;
struct list_head lru_list; struct list_head lru_list;
struct list_head iphash[0]; struct list_head iphash[0];
}; };
...@@ -95,8 +90,7 @@ struct recent_net { ...@@ -95,8 +90,7 @@ struct recent_net {
#endif #endif
}; };
static int recent_net_id __read_mostly; static int recent_net_id;
static inline struct recent_net *recent_pernet(struct net *net) static inline struct recent_net *recent_pernet(struct net *net)
{ {
return net_generic(net, recent_net_id); return net_generic(net, recent_net_id);
...@@ -177,15 +171,12 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr, ...@@ -177,15 +171,12 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
u_int16_t family, u_int8_t ttl) u_int16_t family, u_int8_t ttl)
{ {
struct recent_entry *e; struct recent_entry *e;
unsigned int nstamps_max = t->nstamps_max_mask;
if (t->entries >= ip_list_tot) { if (t->entries >= ip_list_tot) {
e = list_entry(t->lru_list.next, struct recent_entry, lru_list); e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
recent_entry_remove(t, e); recent_entry_remove(t, e);
} }
e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * ip_pkt_list_tot,
nstamps_max += 1;
e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * nstamps_max,
GFP_ATOMIC); GFP_ATOMIC);
if (e == NULL) if (e == NULL)
return NULL; return NULL;
...@@ -206,7 +197,7 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr, ...@@ -206,7 +197,7 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
static void recent_entry_update(struct recent_table *t, struct recent_entry *e) static void recent_entry_update(struct recent_table *t, struct recent_entry *e)
{ {
e->index &= t->nstamps_max_mask; e->index %= ip_pkt_list_tot;
e->stamps[e->index++] = jiffies; e->stamps[e->index++] = jiffies;
if (e->index > e->nstamps) if (e->index > e->nstamps)
e->nstamps = e->index; e->nstamps = e->index;
...@@ -335,7 +326,6 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ...@@ -335,7 +326,6 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
kuid_t uid; kuid_t uid;
kgid_t gid; kgid_t gid;
#endif #endif
unsigned int nstamp_mask;
unsigned int i; unsigned int i;
int ret = -EINVAL; int ret = -EINVAL;
size_t sz; size_t sz;
...@@ -359,33 +349,19 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ...@@ -359,33 +349,19 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
return -EINVAL; return -EINVAL;
if ((info->check_set & XT_RECENT_REAP) && !info->seconds) if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
return -EINVAL; return -EINVAL;
if (info->hit_count >= XT_RECENT_MAX_NSTAMPS) { if (info->hit_count > ip_pkt_list_tot) {
pr_info("hitcount (%u) is larger than allowed maximum (%u)\n", pr_info("hitcount (%u) is larger than "
info->hit_count, XT_RECENT_MAX_NSTAMPS - 1); "packets to be remembered (%u)\n",
info->hit_count, ip_pkt_list_tot);
return -EINVAL; return -EINVAL;
} }
if (info->name[0] == '\0' || if (info->name[0] == '\0' ||
strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN) strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
return -EINVAL; return -EINVAL;
if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot)
nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1;
else if (info->hit_count)
nstamp_mask = roundup_pow_of_two(info->hit_count) - 1;
else
nstamp_mask = 32 - 1;
mutex_lock(&recent_mutex); mutex_lock(&recent_mutex);
t = recent_table_lookup(recent_net, info->name); t = recent_table_lookup(recent_net, info->name);
if (t != NULL) { if (t != NULL) {
if (info->hit_count > t->nstamps_max_mask) {
pr_info("hitcount (%u) is larger than packets to be remembered (%u) for table %s\n",
info->hit_count, t->nstamps_max_mask + 1,
info->name);
ret = -EINVAL;
goto out;
}
t->refcnt++; t->refcnt++;
ret = 0; ret = 0;
goto out; goto out;
...@@ -401,7 +377,6 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ...@@ -401,7 +377,6 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
goto out; goto out;
} }
t->refcnt = 1; t->refcnt = 1;
t->nstamps_max_mask = nstamp_mask;
memcpy(&t->mask, &info->mask, sizeof(t->mask)); memcpy(&t->mask, &info->mask, sizeof(t->mask));
strcpy(t->name, info->name); strcpy(t->name, info->name);
...@@ -522,12 +497,9 @@ static void recent_seq_stop(struct seq_file *s, void *v) ...@@ -522,12 +497,9 @@ static void recent_seq_stop(struct seq_file *s, void *v)
static int recent_seq_show(struct seq_file *seq, void *v) static int recent_seq_show(struct seq_file *seq, void *v)
{ {
const struct recent_entry *e = v; const struct recent_entry *e = v;
struct recent_iter_state *st = seq->private;
const struct recent_table *t = st->table;
unsigned int i; unsigned int i;
i = (e->index - 1) & t->nstamps_max_mask; i = (e->index - 1) % ip_pkt_list_tot;
if (e->family == NFPROTO_IPV4) if (e->family == NFPROTO_IPV4)
seq_printf(seq, "src=%pI4 ttl: %u last_seen: %lu oldest_pkt: %u", seq_printf(seq, "src=%pI4 ttl: %u last_seen: %lu oldest_pkt: %u",
&e->addr.ip, e->ttl, e->stamps[i], e->index); &e->addr.ip, e->ttl, e->stamps[i], e->index);
...@@ -745,9 +717,7 @@ static int __init recent_mt_init(void) ...@@ -745,9 +717,7 @@ static int __init recent_mt_init(void)
{ {
int err; int err;
BUILD_BUG_ON_NOT_POWER_OF_2(XT_RECENT_MAX_NSTAMPS); if (!ip_list_tot || !ip_pkt_list_tot || ip_pkt_list_tot > 255)
if (!ip_list_tot || ip_pkt_list_tot >= XT_RECENT_MAX_NSTAMPS)
return -EINVAL; return -EINVAL;
ip_list_hash_size = 1 << fls(ip_list_tot); ip_list_hash_size = 1 << fls(ip_list_tot);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment