Remote/local Denial of Service vulnerability in SCTP packet/chunk handling

Bug #644209 reported by Thomas Dreibholz
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
linux (Ubuntu)
Fix Released
Medium
Unassigned
Lucid
Fix Released
Medium
Unassigned
Maverick
Fix Released
Medium
Unassigned

Bug Description

Binary package hint: linux-image

sctp_outq_flush() in net/sctp/outqueue.c may call sctp_packet_reset() on a packet structure which has already been filled with chunks. sctp_packet_reset() will not take care of the chunks in its list and only reset the packet length. After that, the SCTP code assumes the packet to be re-initialized and adds further chunks to the structure. The length will be wrong. When actually
trying to transmit the packet, the packet sk_buff structure may be exceeded within sctp_packet_transmit(), resulting in skb_over_panic() => denial of service.

Such a DoS can be triggered by a malicious remote SCTP instance, as follows:
- The remote endpoint has to use two paths (i.e. 2 IP addresses); easy to achieve using an IPv4 address and an IPv6 address -> path A and B.
- The remote user has to trigger the transmission of a HEARTBEAT_ACK on path A. This is trivial, by sending a HEARTBEAT chunk. sctp_outq_flush() will call sctp_packet_config() for the packet on path A. The HEARTBEAT_ACK will be added
to this packet.
- The remote user has to trigger a DATA chunk retransmission on path B. This is trivial, since it only has to send appropriate SACK chunks. sctp_outq_flush() notices that the retransmission is on a different path and calls sctp_packet_config() for the packet on path B. The DATA chunk to be retransmitted is added to this packet.
- The local instance has to send another DATA chunk on path A. This depends on the application, but should be easy to trigger from a remote instance. sctp_outq_flush() notices that the path has changed again, and calls sctp_packet_config() for the packet on path A. This resets the size of the HEARTBEAT_ACK chunk, but the chunk remains in the packet. If size(HEARTBEAT_ACK) + size(DATA) > MTU - overhead, the next call to sctp_packet_transmit() causes the kernel panic => DoS.

PID: 13309 TASK: f6636600 CPU: 1 COMMAND: "scriptingclient"
 #0 [e4d91968] crash_kexec at c0189fea
 #1 [e4d919b4] do_invalid_op at c0104a46
 #2 [e4d91a50] error_code (via invalid_op) at c058d1a1
    EAX: 0000008b EBX: f89e168d ECX: ffffff78 EDX: 00000000 EBP: e4d91ab8
    DS: 007b ESI: f601e000 ES: 007b EDI: e44570e8 GS: 00e0
    CS: 0060 EIP: c04b9d7c ERR: ffffffff EFLAGS: 00010286
 #3 [e4d91a84] skb_over_panic at c04b9d7c
 #4 [e4d91a94] sctp_packet_transmit at f89e1688
 #5 [e4d91ac8] sctp_packet_transmit at f89e1688
 #6 [e4d91b14] sctp_packet_transmit_chunk at f89e1d23
 #7 [e4d91b2c] sctp_outq_flush at f89d78f9
 #8 [e4d91ba8] sctp_outq_uncork at f89d7994
 #9 [e4d91bb0] sctp_cmd_interpreter at f89cce71
#10 [e4d91c00] sctp_side_effects at f89cdbff
#11 [e4d91c30] sctp_do_sm at f89cdd3d
#12 [e4d91cdc] sctp_assoc_bh_rcv at f89d1279
#13 [e4d91d0c] sctp_inq_push at f89d6773
#14 [e4d91d14] sctp_rcv at f89e2e5d
#15 [e4d91d8c] ip_local_deliver_finish at c04ec6e5
#16 [e4d91db0] ip_local_deliver at c04ec93a
#17 [e4d91dcc] ip_rcv_finish at c04ebf98
#18 [e4d91df4] ip_rcv at c04ec449
#19 [e4d91e1c] netif_receive_skb at c04c37a4
#20 [e4d91e58] e1000_receive_skb at f80a45bb
#21 [e4d91e68] e1000_clean_rx_irq at f80a88b6
#22 [e4d91edc] e1000_clean at f80a799d
#23 [e4d91efc] net_rx_action at c04c410a
#24 [e4d91f28] __do_softirq at c0153132
#25 [e4d91f70] do_softirq at c0153290
#26 [e4d91f7c] irq_exit at c01533e0
#27 [e4d91f84] do_IRQ at c0591240
#28 [e4d91fb0] common_interrupt at c0103a2b
    EAX: 9af6e0c6 EBX: b0dad373 ECX: 00000005 EDX: 4d995cbc
    DS: 007b ESI: 598130cd ES: 007b EDI: 00b5dfc0
    SS: 007b ESP: bfca6d80 EBP: bfca6df8 GS: 0033
    CS: 0073 EIP: 0804b816 ERR: ffffff55 EFLAGS: 00000a86

In a similar way, the problem can also be triggered by a local user, having only the permission to establish SCTP associations. Of course, the problem can also occur during normal network operation, just by a retransmission at the wrong time.

A patch by Vlad Yasevic fixes the problem for kernel 2.6.36-rc5:http://www.spinics.net/lists/netdev/msg140903.html.

I have also been able to reproduce the problem with kernel 2.6.32, i.e. at least all kernels from 2.6.32 (Lucid) to 2.6.35 (Maverick) are affected and therefore vulnerable to a DoS attack. The patch above can also be used for these kernel versions.

CVE References

visibility: private → public
Kees Cook (kees)
Changed in linux-meta (Ubuntu):
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Kees Cook (kees) wrote :

Thanks for the report! The kernel team will add this to the list of CVEs to get fixed. Upstream commit is:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4bdab43323b459900578b200a4b8cf9713ac8fab

affects: linux-meta (Ubuntu) → linux (Ubuntu)
Changed in linux (Ubuntu Lucid):
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

This has been fixed on all releases now. Closing bug.

Changed in linux (Ubuntu Lucid):
status: Confirmed → Fix Released
Changed in linux (Ubuntu):
status: Confirmed → Fix Released
Changed in linux (Ubuntu Maverick):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.