sctp: Fix oops when sending queued ASCONF chunks

When we finish processing ASCONF_ACK chunk, we try to send
the next queued ASCONF. This action runs the sctp state
machine recursively and it's not prepared to do so.

kernel BUG at kernel/timer.c:790!
invalid opcode: 0000 [#1] SMP
last sysfs file: /sys/module/ipv6/initstate
Modules linked in: sha256_generic sctp libcrc32c ipv6 dm_multipath
uinput 8139too i2c_piix4 8139cp mii i2c_core pcspkr virtio_net joydev
floppy virtio_blk virtio_pci [last unloaded: scsi_wait_scan]

Pid: 0, comm: swapper Not tainted 2.6.34-rc4 #15 /Bochs
EIP: 0060:[<c044a2ef>] EFLAGS: 00010286 CPU: 0
EIP is at add_timer+0xd/0x1b
EAX: cecbab14 EBX: 000000f0 ECX: c0957b1c EDX: 03595cf4
ESI: cecba800 EDI: cf276f00 EBP: c0957aa0 ESP: c0957aa0
DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
Process swapper (pid: 0, ti=c0956000 task=c0988ba0 task.ti=c0956000)
Stack:
c0957ae0 d1851214 c0ab62e4 c0ab5f26 0500ffff 00000004 00000005 00000004
<0> 00000000 d18694fd 00000004 1666b892 cecba800 cecba800 c0957b14
00000004
<0> c0957b94 d1851b11 ceda8b00 cecba800 cf276f00 00000001 c0957b14
000000d0
Call Trace:
[<d1851214>] ? sctp_side_effects+0x607/0xdfc [sctp]
[<d1851b11>] ? sctp_do_sm+0x108/0x159 [sctp]
[<d1863386>] ? sctp_pname+0x0/0x1d [sctp]
[<d1861a56>] ? sctp_primitive_ASCONF+0x36/0x3b [sctp]
[<d185657c>] ? sctp_process_asconf_ack+0x2a4/0x2d3 [sctp]
[<d184e35c>] ? sctp_sf_do_asconf_ack+0x1dd/0x2b4 [sctp]
[<d1851ac1>] ? sctp_do_sm+0xb8/0x159 [sctp]
[<d1863334>] ? sctp_cname+0x0/0x52 [sctp]
[<d1854377>] ? sctp_assoc_bh_rcv+0xac/0xe1 [sctp]
[<d1858f0f>] ? sctp_inq_push+0x2d/0x30 [sctp]
[<d186329d>] ? sctp_rcv+0x797/0x82e [sctp]

Tested-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Yuansong Qiao <ysqiao@research.ait.ie>
Signed-off-by: Shuaijun Zhang <szhang@research.ait.ie>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Vlad Yasevich and committed by David S. Miller c0786693 a8170c35

+34 -16
+1
include/net/sctp/command.h
··· 107 SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ 108 SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ 109 SCTP_CMD_SEND_MSG, /* Send the whole use message */ 110 SCTP_CMD_LAST 111 } sctp_verb_t; 112
··· 107 SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ 108 SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ 109 SCTP_CMD_SEND_MSG, /* Send the whole use message */ 110 + SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ 111 SCTP_CMD_LAST 112 } sctp_verb_t; 113
-15
net/sctp/sm_make_chunk.c
··· 3318 sctp_chunk_free(asconf); 3319 asoc->addip_last_asconf = NULL; 3320 3321 - /* Send the next asconf chunk from the addip chunk queue. */ 3322 - if (!list_empty(&asoc->addip_chunk_list)) { 3323 - struct list_head *entry = asoc->addip_chunk_list.next; 3324 - asconf = list_entry(entry, struct sctp_chunk, list); 3325 - 3326 - list_del_init(entry); 3327 - 3328 - /* Hold the chunk until an ASCONF_ACK is received. */ 3329 - sctp_chunk_hold(asconf); 3330 - if (sctp_primitive_ASCONF(asoc, asconf)) 3331 - sctp_chunk_free(asconf); 3332 - else 3333 - asoc->addip_last_asconf = asconf; 3334 - } 3335 - 3336 return retval; 3337 } 3338
··· 3318 sctp_chunk_free(asconf); 3319 asoc->addip_last_asconf = NULL; 3320 3321 return retval; 3322 } 3323
+26
net/sctp/sm_sideeffect.c
··· 962 } 963 964 965 966 /* These three macros allow us to pull the debugging code out of the 967 * main flow of sctp_do_sm() to keep attention focused on the real ··· 1639 local_cork = 1; 1640 } 1641 error = sctp_cmd_send_msg(asoc, cmd->obj.msg); 1642 break; 1643 default: 1644 printk(KERN_WARNING "Impossible command: %u, %p\n",
··· 962 } 963 964 965 + /* Sent the next ASCONF packet currently stored in the association. 966 + * This happens after the ASCONF_ACK was succeffully processed. 967 + */ 968 + static void sctp_cmd_send_asconf(struct sctp_association *asoc) 969 + { 970 + /* Send the next asconf chunk from the addip chunk 971 + * queue. 972 + */ 973 + if (!list_empty(&asoc->addip_chunk_list)) { 974 + struct list_head *entry = asoc->addip_chunk_list.next; 975 + struct sctp_chunk *asconf = list_entry(entry, 976 + struct sctp_chunk, list); 977 + list_del_init(entry); 978 + 979 + /* Hold the chunk until an ASCONF_ACK is received. */ 980 + sctp_chunk_hold(asconf); 981 + if (sctp_primitive_ASCONF(asoc, asconf)) 982 + sctp_chunk_free(asconf); 983 + else 984 + asoc->addip_last_asconf = asconf; 985 + } 986 + } 987 + 988 989 /* These three macros allow us to pull the debugging code out of the 990 * main flow of sctp_do_sm() to keep attention focused on the real ··· 1616 local_cork = 1; 1617 } 1618 error = sctp_cmd_send_msg(asoc, cmd->obj.msg); 1619 + break; 1620 + case SCTP_CMD_SEND_NEXT_ASCONF: 1621 + sctp_cmd_send_asconf(asoc); 1622 break; 1623 default: 1624 printk(KERN_WARNING "Impossible command: %u, %p\n",
+7 -1
net/sctp/sm_statefuns.c
··· 3676 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 3677 3678 if (!sctp_process_asconf_ack((struct sctp_association *)asoc, 3679 - asconf_ack)) 3680 return SCTP_DISPOSITION_CONSUME; 3681 3682 abort = sctp_make_abort(asoc, asconf_ack, 3683 sizeof(sctp_errhdr_t));
··· 3676 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 3677 3678 if (!sctp_process_asconf_ack((struct sctp_association *)asoc, 3679 + asconf_ack)) { 3680 + /* Successfully processed ASCONF_ACK. We can 3681 + * release the next asconf if we have one. 3682 + */ 3683 + sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, 3684 + SCTP_NULL()); 3685 return SCTP_DISPOSITION_CONSUME; 3686 + } 3687 3688 abort = sctp_make_abort(asoc, asconf_ack, 3689 sizeof(sctp_errhdr_t));