From: Eugene Teo <eugene@redhat.com> Date: Tue, 15 Mar 2011 01:56:07 -0400 Subject: [net] dccp: fix oops in dccp_rcv_state_process Message-id: <20110315015607.GB4594@infradead.org> Patchwork-id: 33991 O-Subject: [RHEL5.7] BZ#682956 CVE-2011-1093 dccp oops Bugzilla: 682956 CVE: CVE-2011-1093 RH-Acked-by: Thomas Graf <tgraf@redhat.com> RH-Acked-by: Neil Horman <nhorman@redhat.com> RH-Acked-by: Jiri Pirko <jpirko@redhat.com> Backport of upstream commit 720dc34bbbe9493c7bd48b2243058b4e447a929d Fixes CVE-2011-1093. This fixes a bug in the order of dccp_rcv_state_process() that still permitted reception even after closing the socket. A Reset after close thus causes a NULL pointer dereference by not preventing operations on an already torn-down socket. dccp_v4_do_rcv() | | state other than OPEN v dccp_rcv_state_process() | | DCCP_PKT_RESET v dccp_rcv_reset() | v dccp_time_wait() WARNING: at net/ipv4/inet_timewait_sock.c:141 __inet_twsk_hashdance+0x48/0x128() Modules linked in: arc4 ecb carl9170 rt2870sta(C) mac80211 r8712u(C) crc_ccitt ah [<c0038850>] (unwind_backtrace+0x0/0xec) from [<c0055364>] (warn_slowpath_common) [<c0055364>] (warn_slowpath_common+0x4c/0x64) from [<c0055398>] (warn_slowpath_n) [<c0055398>] (warn_slowpath_null+0x1c/0x24) from [<c02b72d0>] (__inet_twsk_hashd) [<c02b72d0>] (__inet_twsk_hashdance+0x48/0x128) from [<c031caa0>] (dccp_time_wai) [<c031caa0>] (dccp_time_wait+0x40/0xc8) from [<c031c15c>] (dccp_rcv_state_proces) [<c031c15c>] (dccp_rcv_state_process+0x120/0x538) from [<c032609c>] (dccp_v4_do_) [<c032609c>] (dccp_v4_do_rcv+0x11c/0x14c) from [<c0286594>] (release_sock+0xac/0) [<c0286594>] (release_sock+0xac/0x110) from [<c031fd34>] (dccp_close+0x28c/0x380) [<c031fd34>] (dccp_close+0x28c/0x380) from [<c02d9a78>] (inet_release+0x64/0x70) The fix is by testing the socket state first. Receiving a packet in Closed state now also produces the required "No connection" Reset reply of RFC 4340, 8.3.1. Signed-off-by: Eugene Teo <eugene@redhat.com> -- net/dccp/input.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) Signed-off-by: Jarod Wilson <jarod@redhat.com> diff --git a/net/dccp/input.c b/net/dccp/input.c index 7f9dc6a..1247181 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -470,6 +470,9 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* Caller (dccp_v4_do_rcv) will send Reset */ dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; return 1; + } else if (sk->sk_state == DCCP_CLOSED) { + dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; + return 1; } if (sk->sk_state != DCCP_REQUESTING) { @@ -543,10 +546,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } switch (sk->sk_state) { - case DCCP_CLOSED: - dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; - return 1; - case DCCP_REQUESTING: /* FIXME: do congestion control initialization */