• Alexey Kodanev's avatar
    sctp: verify size of a new chunk in _sctp_make_chunk() · 1fc74a57
    Alexey Kodanev authored
    
    [ Upstream commit 07f2c7ab ]
    
    When SCTP makes INIT or INIT_ACK packet the total chunk length
    can exceed SCTP_MAX_CHUNK_LEN which leads to kernel panic when
    transmitting these packets, e.g. the crash on sending INIT_ACK:
    
    [  597.804948] skbuff: skb_over_panic: text:00000000ffae06e4 len:120168
                   put:120156 head:000000007aa47635 data:00000000d991c2de
                   tail:0x1d640 end:0xfec0 dev:<NULL>
    ...
    [  597.976970] ------------[ cut here ]------------
    [  598.033408] kernel BUG at net/core/skbuff.c:104!
    [  600.314841] Call Trace:
    [  600.345829]  <IRQ>
    [  600.371639]  ? sctp_packet_transmit+0x2095/0x26d0 [sctp]
    [  600.436934]  skb_put+0x16c/0x200
    [  600.477295]  sctp_packet_transmit+0x2095/0x26d0 [sctp]
    [  600.540630]  ? sctp_packet_config+0x890/0x890 [sctp]
    [  600.601781]  ? __sctp_packet_append_chunk+0x3b4/0xd00 [sctp]
    [  600.671356]  ? sctp_cmp_addr_exact+0x3f/0x90 [sctp]
    [  600.731482]  sctp_outq_flush+0x663/0x30d0 [sctp]
    [  600.788565]  ? sctp_make_init+0xbf0/0xbf0 [sctp]
    [  600.845555]  ? sctp_check_transmitted+0x18f0/0x18f0 [sctp]
    [  600.912945]  ? sctp_outq_tail+0x631/0x9d0 [sctp]
    [  600.969936]  sctp_cmd_interpreter.isra.22+0x3be1/0x5cb0 [sctp]
    [  601.041593]  ? sctp_sf_do_5_1B_init+0x85f/0xc30 [sctp]
    [  601.104837]  ? sctp_generate_t1_cookie_event+0x20/0x20 [sctp]
    [  601.175436]  ? sctp_eat_data+0x1710/0x1710 [sctp]
    [  601.233575]  sctp_do_sm+0x182/0x560 [sctp]
    [  601.284328]  ? sctp_has_association+0x70/0x70 [sctp]
    [  601.345586]  ? sctp_rcv+0xef4/0x32f0 [sctp]
    [  601.397478]  ? sctp6_rcv+0xa/0x20 [sctp]
    ...
    
    Here the chunk size for INIT_ACK packet becomes too big, mostly
    because of the state cookie (INIT packet has large size with
    many address parameters), plus additional server parameters.
    
    Later this chunk causes the panic in skb_put_data():
    
      skb_packet_transmit()
          sctp_packet_pack()
              skb_put_data(nskb, chunk->skb->data, chunk->skb->len);
    
    'nskb' (head skb) was previously allocated with packet->size
    from u16 'chunk->chunk_hdr->length'.
    
    As suggested by Marcelo we should check the chunk's length in
    _sctp_make_chunk() before trying to allocate skb for it and
    discard a chunk if its size bigger than SCTP_MAX_CHUNK_LEN.
    Signed-off-by: default avatarAlexey Kodanev <alexey.kodanev@oracle.com>
    Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leinter@gmail.com>
    Acked-by: default avatarNeil Horman <nhorman@tuxdriver.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    1fc74a57
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
associola.c Loading commit data...
auth.c Loading commit data...
bind_addr.c Loading commit data...
chunk.c Loading commit data...
debug.c Loading commit data...
endpointola.c Loading commit data...
input.c Loading commit data...
inqueue.c Loading commit data...
ipv6.c Loading commit data...
objcnt.c Loading commit data...
offload.c Loading commit data...
output.c Loading commit data...
outqueue.c Loading commit data...
primitive.c Loading commit data...
probe.c Loading commit data...
proc.c Loading commit data...
protocol.c Loading commit data...
sctp_diag.c Loading commit data...
sm_make_chunk.c Loading commit data...
sm_sideeffect.c Loading commit data...
sm_statefuns.c Loading commit data...
sm_statetable.c Loading commit data...
socket.c Loading commit data...
stream.c Loading commit data...
sysctl.c Loading commit data...
transport.c Loading commit data...
tsnmap.c Loading commit data...
ulpevent.c Loading commit data...
ulpqueue.c Loading commit data...