aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-07-31 03:38:31 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-31 03:38:31 -0400
commita8ddc9163c6a16cd62531dba1ec5020484e33b02 (patch)
tree316873162ae914edd6a4f250693017486dede52a
parentae375044d31075a31de5a839e07ded7f67b660aa (diff)
netfilter: ipt_recent: fix race between recent_mt_destroy and proc manipulations
The thing is that recent_mt_destroy first flushes the entries from table with the recent_table_flush and only *after* this removes the proc file, corresponding to that table. Thus, if we manage to write to this file the '+XXX' command we will leak some entries. If we manage to write there a 'clean' command we'll race in two recent_table_flush flows, since the recent_mt_destroy calls this outside the recent_lock. The proper solution as I see it is to remove the proc file first and then go on with flushing the table. This flushing becomes safe w/o the lock, since the table is already inaccessible from the outside. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/netfilter/ipt_recent.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 21cb053f5d7d..3974d7cae5c0 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -305,10 +305,10 @@ static void recent_mt_destroy(const struct xt_match *match, void *matchinfo)
305 spin_lock_bh(&recent_lock); 305 spin_lock_bh(&recent_lock);
306 list_del(&t->list); 306 list_del(&t->list);
307 spin_unlock_bh(&recent_lock); 307 spin_unlock_bh(&recent_lock);
308 recent_table_flush(t);
309#ifdef CONFIG_PROC_FS 308#ifdef CONFIG_PROC_FS
310 remove_proc_entry(t->name, proc_dir); 309 remove_proc_entry(t->name, proc_dir);
311#endif 310#endif
311 recent_table_flush(t);
312 kfree(t); 312 kfree(t);
313 } 313 }
314 mutex_unlock(&recent_mutex); 314 mutex_unlock(&recent_mutex);