diff options
-rw-r--r-- | patches/cve/CVE-2018-5803-sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/patches/cve/CVE-2018-5803-sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch b/patches/cve/CVE-2018-5803-sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch new file mode 100644 index 0000000..8a1a798 --- /dev/null +++ b/patches/cve/CVE-2018-5803-sctp-verify-size-of-a-new-chunk-in-_sctp_make_chunk.patch | |||
@@ -0,0 +1,92 @@ | |||
1 | From 1fc74a57a8ae863c95afedef2510e7e42b194e56 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alexey Kodanev <alexey.kodanev@oracle.com> | ||
3 | Date: Fri, 9 Feb 2018 17:35:23 +0300 | ||
4 | Subject: [PATCH] sctp: verify size of a new chunk in _sctp_make_chunk() | ||
5 | |||
6 | [ Upstream commit 07f2c7ab6f8d0a7e7c5764c4e6cc9c52951b9d9c ] | ||
7 | |||
8 | When SCTP makes INIT or INIT_ACK packet the total chunk length | ||
9 | can exceed SCTP_MAX_CHUNK_LEN which leads to kernel panic when | ||
10 | transmitting these packets, e.g. the crash on sending INIT_ACK: | ||
11 | |||
12 | [ 597.804948] skbuff: skb_over_panic: text:00000000ffae06e4 len:120168 | ||
13 | put:120156 head:000000007aa47635 data:00000000d991c2de | ||
14 | tail:0x1d640 end:0xfec0 dev:<NULL> | ||
15 | ... | ||
16 | [ 597.976970] ------------[ cut here ]------------ | ||
17 | [ 598.033408] kernel BUG at net/core/skbuff.c:104! | ||
18 | [ 600.314841] Call Trace: | ||
19 | [ 600.345829] <IRQ> | ||
20 | [ 600.371639] ? sctp_packet_transmit+0x2095/0x26d0 [sctp] | ||
21 | [ 600.436934] skb_put+0x16c/0x200 | ||
22 | [ 600.477295] sctp_packet_transmit+0x2095/0x26d0 [sctp] | ||
23 | [ 600.540630] ? sctp_packet_config+0x890/0x890 [sctp] | ||
24 | [ 600.601781] ? __sctp_packet_append_chunk+0x3b4/0xd00 [sctp] | ||
25 | [ 600.671356] ? sctp_cmp_addr_exact+0x3f/0x90 [sctp] | ||
26 | [ 600.731482] sctp_outq_flush+0x663/0x30d0 [sctp] | ||
27 | [ 600.788565] ? sctp_make_init+0xbf0/0xbf0 [sctp] | ||
28 | [ 600.845555] ? sctp_check_transmitted+0x18f0/0x18f0 [sctp] | ||
29 | [ 600.912945] ? sctp_outq_tail+0x631/0x9d0 [sctp] | ||
30 | [ 600.969936] sctp_cmd_interpreter.isra.22+0x3be1/0x5cb0 [sctp] | ||
31 | [ 601.041593] ? sctp_sf_do_5_1B_init+0x85f/0xc30 [sctp] | ||
32 | [ 601.104837] ? sctp_generate_t1_cookie_event+0x20/0x20 [sctp] | ||
33 | [ 601.175436] ? sctp_eat_data+0x1710/0x1710 [sctp] | ||
34 | [ 601.233575] sctp_do_sm+0x182/0x560 [sctp] | ||
35 | [ 601.284328] ? sctp_has_association+0x70/0x70 [sctp] | ||
36 | [ 601.345586] ? sctp_rcv+0xef4/0x32f0 [sctp] | ||
37 | [ 601.397478] ? sctp6_rcv+0xa/0x20 [sctp] | ||
38 | ... | ||
39 | |||
40 | Here the chunk size for INIT_ACK packet becomes too big, mostly | ||
41 | because of the state cookie (INIT packet has large size with | ||
42 | many address parameters), plus additional server parameters. | ||
43 | |||
44 | Later this chunk causes the panic in skb_put_data(): | ||
45 | |||
46 | skb_packet_transmit() | ||
47 | sctp_packet_pack() | ||
48 | skb_put_data(nskb, chunk->skb->data, chunk->skb->len); | ||
49 | |||
50 | 'nskb' (head skb) was previously allocated with packet->size | ||
51 | from u16 'chunk->chunk_hdr->length'. | ||
52 | |||
53 | As suggested by Marcelo we should check the chunk's length in | ||
54 | _sctp_make_chunk() before trying to allocate skb for it and | ||
55 | discard a chunk if its size bigger than SCTP_MAX_CHUNK_LEN. | ||
56 | |||
57 | CVE: CVE-2018-5803 | ||
58 | Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.14.y&id=1fc74a57a8ae863c95afedef2510e7e42b194e56] | ||
59 | |||
60 | Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> | ||
61 | Acked-by: Marcelo Ricardo Leitner <marcelo.leinter@gmail.com> | ||
62 | Acked-by: Neil Horman <nhorman@tuxdriver.com> | ||
63 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
64 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
65 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
66 | --- | ||
67 | net/sctp/sm_make_chunk.c | 7 ++++++- | ||
68 | 1 file changed, 6 insertions(+), 1 deletion(-) | ||
69 | |||
70 | diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c | ||
71 | index 514465b03829..e4a400f88168 100644 | ||
72 | --- a/net/sctp/sm_make_chunk.c | ||
73 | +++ b/net/sctp/sm_make_chunk.c | ||
74 | @@ -1378,9 +1378,14 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc, | ||
75 | struct sctp_chunk *retval; | ||
76 | struct sk_buff *skb; | ||
77 | struct sock *sk; | ||
78 | + int chunklen; | ||
79 | + | ||
80 | + chunklen = SCTP_PAD4(sizeof(*chunk_hdr) + paylen); | ||
81 | + if (chunklen > SCTP_MAX_CHUNK_LEN) | ||
82 | + goto nodata; | ||
83 | |||
84 | /* No need to allocate LL here, as this is only a chunk. */ | ||
85 | - skb = alloc_skb(SCTP_PAD4(sizeof(*chunk_hdr) + paylen), gfp); | ||
86 | + skb = alloc_skb(chunklen, gfp); | ||
87 | if (!skb) | ||
88 | goto nodata; | ||
89 | |||
90 | -- | ||
91 | 2.20.1 | ||
92 | |||