From: tuexen Date: Sun, 15 Sep 2019 18:29:45 +0000 (+0000) Subject: When the IP layer calls back into the SCTP layer to perform the SCTP X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e7003e64b018f5f5d8441ec11d701d1b74d048ce;p=freebsd.git When the IP layer calls back into the SCTP layer to perform the SCTP checksum computation, do not assume that the IP header chain and the SCTP common header are in contiguous memory although the SCTP lays out the mbuf chains that way. If there are IP-level options inserted by the IP layer, the constraint is not fulfilled anymore. This issues was found by running syzkaller. Thanks to markj@ who is running an instance which also provides kernel dumps. This allowed me to find this issue. MFC after: 3 days --- diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c index 1c3421a1558..a2771457e71 100644 --- a/sys/netinet/sctp_crc32.c +++ b/sys/netinet/sctp_crc32.c @@ -132,16 +132,16 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset) SCTP_STAT_INCR(sctps_sendswcrc); offset += offsetof(struct sctphdr, checksum); - if (offset + sizeof(uint32_t) > (uint32_t)(m->m_len)) { + if (offset + sizeof(uint32_t) > (uint32_t)(m->m_pkthdr.len)) { #ifdef INVARIANTS - panic("sctp_delayed_cksum(): m->m_len: %d, offset: %u.", - m->m_len, offset); + panic("sctp_delayed_cksum(): m->m_pkthdr.len: %d, offset: %u.", + m->m_pkthdr.len, offset); #else - SCTP_PRINTF("sctp_delayed_cksum(): m->m_len: %d, offset: %u.\n", - m->m_len, offset); + SCTP_PRINTF("sctp_delayed_cksum(): m->m_pkthdr.len: %d, offset: %u.\n", + m->m_pkthdr.len, offset); #endif return; } - *(uint32_t *)(m->m_data + offset) = checksum; + m_copyback(m, (int)offset, (int)sizeof(uint32_t), (caddr_t)&checksum); } #endif