[kernel] r16831 - in dists/lenny-security/linux-2.6/debian: . patches/bugfix/all patches/series
Dann Frazier
dannf at alioth.debian.org
Mon Jan 17 20:07:22 UTC 2011
Author: dannf
Date: Mon Jan 17 20:07:18 2011
New Revision: 16831
Log:
sctp: a race between ICMP protocol unreachable and connect() (CVE-2010-4526)
Added:
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/sctp-fix-race-between-ICMP-protocol-unreachable-and-connect.patch
Modified:
dists/lenny-security/linux-2.6/debian/changelog
dists/lenny-security/linux-2.6/debian/patches/series/26lenny2
Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog Mon Jan 17 20:02:03 2011 (r16830)
+++ dists/lenny-security/linux-2.6/debian/changelog Mon Jan 17 20:07:18 2011 (r16831)
@@ -19,6 +19,7 @@
real users is insignificant.
* econet: Fix crash in aun_incoming() (CVE-2010-4343)
* install_special_mapping skips security_file_mmap check (CVE-2010-4346)
+ * sctp: a race between ICMP protocol unreachable and connect() (CVE-2010-4526)
[ Moritz Muehlenhoff ]
* blkback/blktap/netback: Fix CVE-2010-3699
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/sctp-fix-race-between-ICMP-protocol-unreachable-and-connect.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/sctp-fix-race-between-ICMP-protocol-unreachable-and-connect.patch Mon Jan 17 20:07:18 2011 (r16831)
@@ -0,0 +1,177 @@
+commit a4ee11e76769b8fc37c4a49972ef4588e8fd19fc
+Author: Vlad Yasevich <vladislav.yasevich at hp.com>
+Date: Thu May 6 00:56:07 2010 -0700
+
+ sctp: Fix a race between ICMP protocol unreachable and connect()
+
+ ICMP protocol unreachable handling completely disregarded
+ the fact that the user may have locked the socket. It proceeded
+ to destroy the association, even though the user may have
+ held the lock and had a ref on the association. This resulted
+ in the following:
+
+ Attempt to release alive inet socket f6afcc00
+
+ =========================
+ [ BUG: held lock freed! ]
+ -------------------------
+ somenu/2672 is freeing memory f6afcc00-f6afcfff, with a lock still held
+ there!
+ (sk_lock-AF_INET){+.+.+.}, at: [<c122098a>] sctp_connect+0x13/0x4c
+ 1 lock held by somenu/2672:
+ #0: (sk_lock-AF_INET){+.+.+.}, at: [<c122098a>] sctp_connect+0x13/0x4c
+
+ stack backtrace:
+ Pid: 2672, comm: somenu Not tainted 2.6.32-telco #55
+ Call Trace:
+ [<c1232266>] ? printk+0xf/0x11
+ [<c1038553>] debug_check_no_locks_freed+0xce/0xff
+ [<c10620b4>] kmem_cache_free+0x21/0x66
+ [<c1185f25>] __sk_free+0x9d/0xab
+ [<c1185f9c>] sk_free+0x1c/0x1e
+ [<c1216e38>] sctp_association_put+0x32/0x89
+ [<c1220865>] __sctp_connect+0x36d/0x3f4
+ [<c122098a>] ? sctp_connect+0x13/0x4c
+ [<c102d073>] ? autoremove_wake_function+0x0/0x33
+ [<c12209a8>] sctp_connect+0x31/0x4c
+ [<c11d1e80>] inet_dgram_connect+0x4b/0x55
+ [<c11834fa>] sys_connect+0x54/0x71
+ [<c103a3a2>] ? lock_release_non_nested+0x88/0x239
+ [<c1054026>] ? might_fault+0x42/0x7c
+ [<c1054026>] ? might_fault+0x42/0x7c
+ [<c11847ab>] sys_socketcall+0x6d/0x178
+ [<c10da994>] ? trace_hardirqs_on_thunk+0xc/0x10
+ [<c1002959>] syscall_call+0x7/0xb
+
+ This was because the sctp_wait_for_connect() would aqcure the socket
+ lock and then proceed to release the last reference count on the
+ association, thus cause the fully destruction path to finish freeing
+ the socket.
+
+ The simplest solution is to start a very short timer in case the socket
+ is owned by user. When the timer expires, we can do some verification
+ and be able to do the release properly.
+
+ Signed-off-by: Vlad Yasevich <vladislav.yasevich at hp.com>
+ Signed-off-by: David S. Miller <davem at davemloft.net>
+ [dannf: backported to Debian's 2.6.26]
+
+diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
+index 029a54a..22757ba 100644
+--- a/include/net/sctp/sm.h
++++ b/include/net/sctp/sm.h
+@@ -277,6 +277,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
+ /* 2nd level prototypes */
+ void sctp_generate_t3_rtx_event(unsigned long peer);
+ void sctp_generate_heartbeat_event(unsigned long peer);
++void sctp_generate_proto_unreach_event(unsigned long peer);
+
+ void sctp_ootb_pkt_free(struct sctp_packet *);
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 71e8509..605d4f7 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -997,6 +997,9 @@ struct sctp_transport {
+ /* Heartbeat timer is per destination. */
+ struct timer_list hb_timer;
+
++ /* Timer to handle ICMP proto unreachable envets */
++ struct timer_list proto_unreach_timer;
++
+ /* Since we're using per-destination retransmission timers
+ * (see above), we're also using per-destination "transmitted"
+ * queues. This probably ought to be a private struct
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index ca6b022..3ca7795 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -411,11 +411,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
+ {
+ SCTP_DEBUG_PRINTK("%s\n", __func__);
+
+- sctp_do_sm(SCTP_EVENT_T_OTHER,
+- SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+- asoc->state, asoc->ep, asoc, t,
+- GFP_ATOMIC);
++ if (sock_owned_by_user(sk)) {
++ if (timer_pending(&t->proto_unreach_timer))
++ return;
++ else {
++ if (!mod_timer(&t->proto_unreach_timer,
++ jiffies + (HZ/20)))
++ sctp_association_hold(asoc);
++ }
++
++ } else {
++ if (timer_pending(&t->proto_unreach_timer) &&
++ del_timer(&t->proto_unreach_timer))
++ sctp_association_put(asoc);
+
++ sctp_do_sm(SCTP_EVENT_T_OTHER,
++ SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
++ asoc->state, asoc->ep, asoc, t,
++ GFP_ATOMIC);
++ }
+ }
+
+ /* Common lookup code for icmp/icmpv6 error handler. */
+diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
+index 23a9f1a..8fbb093 100644
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -388,6 +388,41 @@ out_unlock:
+ sctp_transport_put(transport);
+ }
+
++/* Handle the timeout of the ICMP protocol unreachable timer. Trigger
++ * the correct state machine transition that will close the association.
++ */
++void sctp_generate_proto_unreach_event(unsigned long data)
++{
++ struct sctp_transport *transport = (struct sctp_transport *) data;
++ struct sctp_association *asoc = transport->asoc;
++
++ sctp_bh_lock_sock(asoc->base.sk);
++ if (sock_owned_by_user(asoc->base.sk)) {
++ SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
++
++ /* Try again later. */
++ if (!mod_timer(&transport->proto_unreach_timer,
++ jiffies + (HZ/20)))
++ sctp_association_hold(asoc);
++ goto out_unlock;
++ }
++
++ /* Is this structure just waiting around for us to actually
++ * get destroyed?
++ */
++ if (asoc->base.dead)
++ goto out_unlock;
++
++ sctp_do_sm(SCTP_EVENT_T_OTHER,
++ SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
++ asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
++
++out_unlock:
++ sctp_bh_unlock_sock(asoc->base.sk);
++ sctp_association_put(asoc);
++}
++
++
+ /* Inject a SACK Timeout event into the state machine. */
+ static void sctp_generate_sack_event(unsigned long data)
+ {
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 3f34f61..fb68650 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -104,6 +104,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+ (unsigned long)peer);
+ setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
+ (unsigned long)peer);
++ setup_timer(&peer->proto_unreach_timer,
++ sctp_generate_proto_unreach_event, (unsigned long)peer);
+
+ /* Initialize the 64-bit random nonce sent with heartbeat. */
+ get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
Modified: dists/lenny-security/linux-2.6/debian/patches/series/26lenny2
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/26lenny2 Mon Jan 17 20:02:03 2011 (r16830)
+++ dists/lenny-security/linux-2.6/debian/patches/series/26lenny2 Mon Jan 17 20:07:18 2011 (r16831)
@@ -16,3 +16,4 @@
+ debian/econet-Disable-auto-loading-as-mitigation-against-lo.patch
+ bugfix/all/econet-fix-crash-in-aun_incoming.patch
+ bugfix/all/install_special_mapping-skips-security_file_mmap_check.patch
++ bugfix/all/sctp-fix-race-between-ICMP-protocol-unreachable-and-connect.patch
More information about the Kernel-svn-changes
mailing list