From 07f055d4a539e061a10f51a420bede843d9659dc Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Fri, 9 Mar 2018 20:32:40 +0100 Subject: [PATCH] sctp: verify size of a new chunk in _sctp_make_chunk() (CVE-2018-5803) --- debian/changelog | 1 + ...e-of-a-new-chunk-in-_sctp_make_chunk.patch | 86 +++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 88 insertions(+) create mode 100644 debian/patches/bugfix/all/sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch diff --git a/debian/changelog b/debian/changelog index cd51e1c61..2075c96a8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ linux (4.15.4-2) UNRELEASED; urgency=medium * Add ABI reference for 4.15.0-1 * ALSA: seq: Fix racy pool initializations (CVE-2018-7566) + * sctp: verify size of a new chunk in _sctp_make_chunk() (CVE-2018-5803) -- Salvatore Bonaccorso Tue, 20 Feb 2018 21:51:39 +0100 diff --git a/debian/patches/bugfix/all/sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch b/debian/patches/bugfix/all/sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch new file mode 100644 index 000000000..91f35a85e --- /dev/null +++ b/debian/patches/bugfix/all/sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch @@ -0,0 +1,86 @@ +From: Alexey Kodanev +Date: Fri, 9 Feb 2018 17:35:23 +0300 +Subject: sctp: verify size of a new chunk in _sctp_make_chunk() +Origin: https://git.kernel.org/linus/07f2c7ab6f8d0a7e7c5764c4e6cc9c52951b9d9c +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5803 + +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: +... +[ 597.976970] ------------[ cut here ]------------ +[ 598.033408] kernel BUG at net/core/skbuff.c:104! +[ 600.314841] Call Trace: +[ 600.345829] +[ 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: Alexey Kodanev +Acked-by: Marcelo Ricardo Leitner +Acked-by: Neil Horman +Signed-off-by: David S. Miller +--- + net/sctp/sm_make_chunk.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c +index 793b05ec692b..d01475f5f710 100644 +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -1380,9 +1380,14 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc, + struct sctp_chunk *retval; + struct sk_buff *skb; + struct sock *sk; ++ int chunklen; ++ ++ chunklen = SCTP_PAD4(sizeof(*chunk_hdr) + paylen); ++ if (chunklen > SCTP_MAX_CHUNK_LEN) ++ goto nodata; + + /* No need to allocate LL here, as this is only a chunk. */ +- skb = alloc_skb(SCTP_PAD4(sizeof(*chunk_hdr) + paylen), gfp); ++ skb = alloc_skb(chunklen, gfp); + if (!skb) + goto nodata; + +-- +2.16.2 + diff --git a/debian/patches/series b/debian/patches/series index 729b1a0e9..3e64b6ce5 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -120,6 +120,7 @@ features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch # Security fixes debian/i386-686-pae-pci-set-pci-nobios-by-default.patch bugfix/all/ALSA-seq-Fix-racy-pool-initializations.patch +bugfix/all/sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch # Fix exported symbol versions bugfix/all/module-disable-matching-missing-version-crc.patch