From: Amin Azez <azez@ufomechanic.net>
To: netfilter-devel@lists.netfilter.org
Subject: ipt_recent fix
Date: Fri, 17 Feb 2006 17:37:53 +0000 [thread overview]
Message-ID: <dt51lh$b63$1@sea.gmane.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 1216 bytes --]
Here is a fix for ipt_recent.
The problem is that curr_table[x].hash_entry=0 (for all x)
So all pristine (never used) curr_table entries claim to have hash pos 0.
So when we add new items to the hash and do:
hash_table[r_list[location].hash_entry] = -1;
to use the oldest (used or unused) location - if it is unused we trash
anything that really has hash pos 0 already allocated.
This can be reproduced with this:
# iptables -A FORWARD -d 1.1.1.1 -m recent --name TEST1 --set
# G=1 ; while test $G -lt 17 ; do echo $G ; echo 1.1.1.$G> \
/proc/net/ipt_recent/TEST1 ; G=$(($G+1)) ; dmesg -c ; cat \
/proc/net/ipt_recent/TEST1 | head ; done > x
the 13th item has hash of 0 and gets trashed when the 14th item is added
without this patch.
We should only trash it then if we _know_ it has been used before and
therefore is REALLY at the position it claims...
This patch makes sure that items claiming to have a hash entry really do
have that hash entry before destroying that hash entry.
This patch also adds counting of the number of hash entries in
preparation for conditions based on the number of entries in the recent
table rule; patch for that to follow next week.
Any comments on this?
Sam
[-- Attachment #2: ipt_recent.patch --]
[-- Type: text/x-patch, Size: 3157 bytes --]
--- ./net/ipv4/netfilter/ipt_recent.c.nolimit 2006-02-15 16:34:20.000000000 +0000
+++ ./net/ipv4/netfilter/ipt_recent.c 2006-02-17 17:23:00.000000000 +0000
@@ -70,7 +70,11 @@
/* Structure of our linked list of tables of recent lists. */
struct recent_ip_tables {
char name[IPT_RECENT_NAME_LEN];
+ /* number of entries in list *table */
+ int entry_count;
+ /* number of reference to this structure from iptables rules */
int count;
+ /* an index increased with each operation which maps time_info[x].position to a position in table */
int time_pos;
struct recent_ip_list *table;
struct recent_ip_tables *next;
@@ -139,6 +143,7 @@
curr_table = (struct recent_ip_tables*) data;
spin_lock_bh(&curr_table->list_lock);
+ len += sprintf(buffer+len,"count=%d\n",curr_table->entry_count);
for(count = 0; count < ip_list_tot; count++) {
if(!curr_table->table[count].addr) continue;
last_len = len;
@@ -216,6 +221,7 @@
used += 5;
spin_lock_bh(&curr_table->list_lock);
curr_table->time_pos = 0;
+ curr_table->entry_count = 0;
for(count = 0; count < ip_list_hash_size; count++) {
curr_table->hash_table[count] = -1;
}
@@ -500,7 +506,27 @@
/* New item found and IPT_RECENT_SET, so we need to add it */
location = time_info[curr_table->time_pos].position;
- hash_table[r_list[location].hash_entry] = -1;
+ /*
+ location is the next slot in r_list that we will use.
+ Maybe it is already used and we need to remove it fromthe hash.
+ If it is used then:
+ 1) hash_table[r_list[location].hash_entry]=location
+ Which is to say that anything claiming to have a hash entry
+ should also be pointed to BY that hash entry.
+ This only comes up becase by default r_list[x].hash_entry=0
+ i.e. all items claim to have hash entry 0, so if a real
+ item has hash slot 0 it gets trashed because of lies.
+ SO: If r_list[location].hash_entry]==0 we are in warning condition
+ and need to double check that hash_table reciprocates before we
+ set the hash_table entry to -1 (it may not really belong)
+ This would work;
+ if (r_list[location].hash_entry!=0 || hash_table[0]==location) hash_table[r_list[location].hash_entry] = -1;
+ but we want to combine with a counter for new entries
+ */
+ /* increase counter if this is a new item */
+ if (hash_table[r_list[location].hash_entry]!=location) curr_table->entry_count++;
+ else hash_table[r_list[location].hash_entry] = -1;
+
hash_table[hash_result] = location;
memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
r_list[location].time_pos = curr_table->time_pos;
@@ -633,6 +659,7 @@
r_list[location].ttl = 0;
memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
r_list[location].oldest_pkt = 0;
+ curr_table->entry_count--;
ans = !info->invert;
}
spin_unlock_bh(&curr_table->list_lock);
@@ -719,6 +746,7 @@
curr_table->next = NULL;
curr_table->count = 1;
curr_table->time_pos = 0;
+ curr_table->entry_count = 0;
strncpy(curr_table->name,info->name,IPT_RECENT_NAME_LEN);
curr_table->name[IPT_RECENT_NAME_LEN-1] = '\0';
next reply other threads:[~2006-02-17 17:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-17 17:37 Amin Azez [this message]
2006-02-20 16:12 ` [patch] ipt_recent Amin Azez
2006-03-04 10:00 ` Patrick McHardy
2006-03-07 15:48 ` Amin Azez
2006-03-08 12:16 ` Patrick McHardy
2006-03-13 17:47 ` ipt_recent patch Amin Azez
2006-03-22 14:26 ` Stephen Frost
2006-05-03 9:32 ` Amin Azez
2006-05-03 11:41 ` Amin Azez
2006-03-22 12:04 ` [patch] ipt_recent Amin Azez
2006-02-21 11:16 ` BUG: More ipt_recent queries Amin Azez
2006-02-21 16:28 ` Amin Azez
2006-03-04 10:13 ` Patrick McHardy
2006-03-06 3:04 ` Stephen Frost
2006-03-07 15:46 ` Amin Azez
2006-03-04 10:10 ` ipt_recent fix Patrick McHardy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='dt51lh$b63$1@sea.gmane.org' \
--to=azez@ufomechanic.net \
--cc=netfilter-devel@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.