linux-uconsole/net/netfilter
Sven Wegener fb97898fa8 ipvs: Add missing locking during connection table hashing and unhashing
commit aea9d711f3 upstream.

The code that hashes and unhashes connections from the connection table
is missing locking of the connection being modified, which opens up a
race condition and results in memory corruption when this race condition
is hit.

Here is what happens in pretty verbose form:

CPU 0					CPU 1
------------				------------
An active connection is terminated and
we schedule ip_vs_conn_expire() on this
CPU to expire this connection.

					IRQ assignment is changed to this CPU,
					but the expire timer stays scheduled on
					the other CPU.

					New connection from same ip:port comes
					in right before the timer expires, we
					find the inactive connection in our
					connection table and get a reference to
					it. We proper lock the connection in
					tcp_state_transition() and read the
					connection flags in set_tcp_state().

ip_vs_conn_expire() gets called, we
unhash the connection from our
connection table and remove the hashed
flag in ip_vs_conn_unhash(), without
proper locking!

					While still holding proper locks we
					write the connection flags in
					set_tcp_state() and this sets the hashed
					flag again.

ip_vs_conn_expire() fails to expire the
connection, because the other CPU has
incremented the reference count. We try
to re-insert the connection into our
connection table, but this fails in
ip_vs_conn_hash(), because the hashed
flag has been set by the other CPU. We
re-schedule execution of
ip_vs_conn_expire(). Now this connection
has the hashed flag set, but isn't
actually hashed in our connection table
and has a dangling list_head.

					We drop the reference we held on the
					connection and schedule the expire timer
					for timeouting the connection on this
					CPU. Further packets won't be able to
					find this connection in our connection
					table.

					ip_vs_conn_expire() gets called again,
					we think it's already hashed, but the
					list_head is dangling and while removing
					the connection from our connection table
					we write to the memory location where
					this list_head points to.

The result will probably be a kernel oops at some other point in time.

This race condition is pretty subtle, but it can be triggered remotely.
It needs the IRQ assignment change or another circumstance where packets
coming from the same ip:port for the same service are being processed on
different CPUs. And it involves hitting the exact time at which
ip_vs_conn_expire() gets called. It can be avoided by making sure that
all packets from one connection are always processed on the same CPU and
can be made harder to exploit by changing the connection timeouts to
some custom values.

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Acked-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-08-02 10:20:50 -07:00
..
ipvs ipvs: Add missing locking during connection table hashing and unhashing 2010-08-02 10:20:50 -07:00
core.c netfilter: remove unneeded goto 2009-02-18 16:29:08 +01:00
Kconfig Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 2009-06-15 03:02:23 -07:00
Makefile netfilter: passive OS fingerprint xtables match 2009-06-08 17:01:51 +02:00
nf_conntrack_acct.c trivial: Fix paramater/parameter typo in dmesg and source comments 2009-06-12 18:01:46 +02:00
nf_conntrack_amanda.c net: replace uses of __constant_{endian} 2009-02-01 00:45:17 -08:00
nf_conntrack_core.c netfilter: nf_conntrack: fix hash resizing with namespaces 2010-02-23 07:37:53 -08:00
nf_conntrack_ecache.c netfilter: conntrack: optional reliable conntrack event delivery 2009-06-13 12:30:52 +02:00
nf_conntrack_expect.c netfilter: nf_conntrack: fix hash resizing with namespaces 2010-02-23 07:37:53 -08:00
nf_conntrack_extend.c nf_conntrack: Use rcu_barrier() 2009-06-25 16:32:52 +02:00
nf_conntrack_ftp.c netfilter: nf_ct_ftp: fix out of bounds read in update_nl_seq() 2010-01-18 10:19:41 -08:00
nf_conntrack_h323_asn1.c [NETFILTER]: nf_conntrack_h323: constify and annotate H.323 helper 2008-01-31 19:28:07 -08:00
nf_conntrack_h323_main.c net: replace uses of __constant_{endian} 2009-02-01 00:45:17 -08:00
nf_conntrack_h323_types.c [NETFILTER]: nf_conntrack_h323: constify and annotate H.323 helper 2008-01-31 19:28:07 -08:00
nf_conntrack_helper.c netfilter: nf_conntrack: fix hash resizing with namespaces 2010-02-23 07:37:53 -08:00
nf_conntrack_irc.c netfilter: fix endian bug in conntrack printks 2009-03-28 23:55:57 -07:00
nf_conntrack_l3proto_generic.c [NETFILTER]: nf_conntrack: use bool type in struct nf_conntrack_l3proto 2008-04-14 11:15:52 +02:00
nf_conntrack_netbios_ns.c net: skb->rtable accessor 2009-06-03 02:51:02 -07:00
nf_conntrack_netlink.c netfilter: nf_conntrack: fix hash resizing with namespaces 2010-02-23 07:37:53 -08:00
nf_conntrack_pptp.c Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-03-26 15:23:24 -07:00
nf_conntrack_proto.c netfilter: ctnetlink: add callbacks to the per-proto nlattrs 2009-03-25 18:24:48 +01:00
nf_conntrack_proto_dccp.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6 2009-06-11 16:00:49 +02:00
nf_conntrack_proto_generic.c netfilter: change generic l4 protocol number 2009-02-18 16:28:35 +01:00
nf_conntrack_proto_gre.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6 2009-06-11 16:00:49 +02:00
nf_conntrack_proto_sctp.c netfilter: nf_conntrack: use per-conntrack locks for protocol data 2009-06-10 14:32:47 +02:00
nf_conntrack_proto_tcp.c netfilter: nf_nat: fix NAT issue in 2.6.30.4+ 2009-11-06 00:43:42 -08:00
nf_conntrack_proto_udp.c netfilter: nf_conntrack: calculate per-protocol nlattr size 2009-03-25 21:53:39 +01:00
nf_conntrack_proto_udplite.c netfilter: nf_ct_dccp/udplite: fix protocol registration error 2009-04-24 15:37:44 +02:00
nf_conntrack_sane.c netfilter: nf_conntrack: connection tracking helper name persistent aliases 2008-11-17 16:01:42 +01:00
nf_conntrack_sip.c netfilter: nf_conntrack: connection tracking helper name persistent aliases 2008-11-17 16:01:42 +01:00
nf_conntrack_standalone.c netfilter: nf_conntrack: fix hash resizing with namespaces 2010-02-23 07:37:53 -08:00
nf_conntrack_tftp.c netfilter: nf_conntrack: connection tracking helper name persistent aliases 2008-11-17 16:01:42 +01:00
nf_internals.h netfilter: Use unsigned types for hooknum and pf vars 2008-10-08 11:35:00 +02:00
nf_log.c netfilter: nf_log: fix sleeping function called from invalid context in seq_show() 2009-11-19 13:16:31 -08:00
nf_queue.c netfilter: queue: use NFPROTO_ for queue callsites 2009-05-08 10:30:46 +02:00
nf_sockopt.c net: Make setsockopt() optlen be unsigned. 2009-09-30 16:12:20 -07:00
nf_tproxy_core.c net: Partially allow skb destructors to be used on receive path 2009-02-04 16:55:27 -08:00
nfnetlink.c netfilter: nfnetlink: constify message attributes and headers 2009-08-25 16:07:58 +02:00
nfnetlink_log.c netfilter: nfnetlink: constify message attributes and headers 2009-08-25 16:07:58 +02:00
nfnetlink_queue.c netfilter: nfnetlink: constify message attributes and headers 2009-08-25 16:07:58 +02:00
x_tables.c mm: replace various uses of num_physpages by totalram_pages 2009-09-22 07:17:38 -07:00
xt_CLASSIFY.c netfilter: xtables: move extension arguments into compound structure (4/6) 2008-10-08 11:35:19 +02:00
xt_cluster.c netfilter: fix some sparse endianess warnings 2009-06-22 14:15:02 +02:00
xt_comment.c netfilter: xtables: use NFPROTO_UNSPEC in more extensions 2008-10-08 11:35:20 +02:00
xt_connbytes.c netfilter: xtables: cut down on static data for family-independent extensions 2008-10-08 11:35:20 +02:00
xt_connlimit.c netfilter: xt_connlimit: fix regression caused by zero family value 2009-11-06 18:08:32 -08:00
xt_CONNMARK.c netfilter: xtables: remove xt_CONNMARK v0 2009-08-10 12:25:11 +02:00
xt_connmark.c netfilter: xtables: remove xt_connmark v0 2009-08-10 12:25:12 +02:00
xt_CONNSECMARK.c netfilter: xtables: cut down on static data for family-independent extensions 2008-10-08 11:35:20 +02:00
xt_conntrack.c netfilter: xtables: fix conntrack match v1 ipt-save output 2010-01-28 15:01:04 -08:00
xt_dccp.c nf/dccp: merge errorpaths 2008-12-14 23:19:02 -08:00
xt_dscp.c netfilter: xtables: remove xt_TOS v0 2009-08-10 12:25:11 +02:00
xt_DSCP.c netfilter: xtables: remove xt_TOS v0 2009-08-10 12:25:11 +02:00
xt_esp.c netfilter: xtables: move extension arguments into compound structure (2/6) 2008-10-08 11:35:18 +02:00
xt_hashlimit.c mm: replace various uses of num_physpages by totalram_pages 2009-09-22 07:17:38 -07:00
xt_helper.c netfilter: xtables: cut down on static data for family-independent extensions 2008-10-08 11:35:20 +02:00
xt_hl.c netfilter: Combine ipt_ttl and ip6t_hl source 2009-02-18 18:39:31 +01:00
xt_HL.c netfilter: Combine ipt_TTL and ip6t_HL source 2009-02-18 18:38:40 +01:00
xt_iprange.c netfilter: xtables: remove xt_iprange v0 2009-08-10 13:09:44 +02:00
xt_LED.c netfilter: x_tables: add LED trigger target 2009-02-20 10:55:14 +01:00
xt_length.c netfilter: xtables: move extension arguments into compound structure (1/6) 2008-10-08 11:35:18 +02:00
xt_limit.c netfilter: xt_limit: fix invalid return code in limit_mt_check() 2009-11-23 13:37:23 +01:00
xt_mac.c netfilter: xtables: use NFPROTO_UNSPEC in more extensions 2008-10-08 11:35:20 +02:00
xt_mark.c netfilter: xtables: remove xt_mark v0 2009-08-10 13:09:45 +02:00
xt_MARK.c netfilter: xtables: remove xt_MARK v0, v1 2009-08-10 12:25:12 +02:00
xt_multiport.c netfilter: xtables: move extension arguments into compound structure (2/6) 2008-10-08 11:35:18 +02:00
xt_NFLOG.c netfilter: xt_NFLOG: don't call nf_log_packet in NFLOG module. 2008-11-04 14:21:08 +01:00
xt_NFQUEUE.c netfilter: fix some sparse endianess warnings 2009-06-22 14:15:02 +02:00
xt_NOTRACK.c netfilter: xtables: use NFPROTO_UNSPEC in more extensions 2008-10-08 11:35:20 +02:00
xt_osf.c netfilter: xt_osf: fix xt_osf_remove_callback() return value 2009-11-19 13:16:26 -08:00
xt_owner.c netfilter: xtables: remove xt_owner v0 2009-08-10 13:32:30 +02:00
xt_physdev.c netfilter: factorize ifname_compare() 2009-03-25 17:31:52 +01:00
xt_pkttype.c netfilter: xtables: cut down on static data for family-independent extensions 2008-10-08 11:35:20 +02:00
xt_policy.c net: skb->dst accessors 2009-06-03 02:51:04 -07:00
xt_quota.c netfilter: xt_quota: fix wrong return value (error case) 2009-08-23 19:09:23 -07:00
xt_rateest.c netfilter: xt_rateest: fix comparison with self 2009-06-22 14:17:12 +02:00
xt_RATEEST.c net: restore gnet_stats_basic to previous definition 2009-08-17 21:33:49 -07:00
xt_realm.c net: skb->dst accessors 2009-06-03 02:51:04 -07:00
xt_recent.c netfilter: xt_recent: fix regression in rules using a zero hit_count 2010-04-01 15:58:47 -07:00
xt_sctp.c netfilter: xt_sctp: sctp chunk mapping doesn't work 2009-02-09 14:34:56 -08:00
xt_SECMARK.c netfilter: xtables: move extension arguments into compound structure (6/6) 2008-10-08 11:35:19 +02:00
xt_socket.c netfilter: xt_socket: added new revision of the 'socket' match supporting flags 2009-06-09 15:16:34 +02:00
xt_state.c netfilter: xtables: move extension arguments into compound structure (3/6) 2008-10-08 11:35:19 +02:00
xt_statistic.c netfilter: xtables: avoid pointer to self 2009-03-16 15:35:29 +01:00
xt_string.c netfilter: xtables: move extension arguments into compound structure (3/6) 2008-10-08 11:35:19 +02:00
xt_TCPMSS.c net: skb->dst accessors 2009-06-03 02:51:04 -07:00
xt_tcpmss.c netfilter: xtables: move extension arguments into compound structure (1/6) 2008-10-08 11:35:18 +02:00
xt_TCPOPTSTRIP.c netfilter: xtables: move extension arguments into compound structure (4/6) 2008-10-08 11:35:19 +02:00
xt_tcpudp.c netfilter: xtables: move extension arguments into compound structure (2/6) 2008-10-08 11:35:18 +02:00
xt_time.c netfilter 08/09: xt_time: print timezone for user information 2009-01-12 21:18:36 -08:00
xt_TPROXY.c netfilter: xtables: move extension arguments into compound structure (5/6) 2008-10-08 11:35:19 +02:00
xt_TRACE.c netfilter: xtables: move extension arguments into compound structure (4/6) 2008-10-08 11:35:19 +02:00
xt_u32.c netfilter: xtables: move extension arguments into compound structure (1/6) 2008-10-08 11:35:18 +02:00