Improve input validation of the spp_pathmtu field in the
SCTP_PEER_ADDR_PARAMS socket option. The code in the stack assumes sane values for the MTU. This issue was found by running an instance of syzkaller. MFC after: 1 week
This commit is contained in:
parent
d0d8c0977c
commit
ac1d75d23a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356270
@ -1,3 +1,4 @@
|
||||
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
@ -585,8 +586,10 @@ struct sctp_error_auth_invalid_hmac {
|
||||
#define SCTP_MOBILITY_PRIM_DELETED 0x00000004
|
||||
|
||||
|
||||
#define SCTP_SMALLEST_PMTU 512 /* smallest pmtu allowed when disabling PMTU
|
||||
* discovery */
|
||||
/* Smallest PMTU allowed when disabling PMTU discovery */
|
||||
#define SCTP_SMALLEST_PMTU 512
|
||||
/* Largest PMTU allowed when disabling PMTU discovery */
|
||||
#define SCTP_LARGEST_PMTU 65536
|
||||
|
||||
#undef SCTP_PACKED
|
||||
|
||||
|
@ -5363,6 +5363,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) &&
|
||||
((paddrp->spp_pathmtu < SCTP_SMALLEST_PMTU) ||
|
||||
(paddrp->spp_pathmtu > SCTP_LARGEST_PMTU))) {
|
||||
if (stcb)
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (stcb != NULL) {
|
||||
/************************TCB SPECIFIC SET ******************/
|
||||
@ -5394,7 +5402,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
|
||||
}
|
||||
}
|
||||
if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
|
||||
if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
|
||||
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11);
|
||||
@ -5536,7 +5544,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
}
|
||||
sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
|
||||
}
|
||||
if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
|
||||
if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
|
||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
|
||||
@ -5635,9 +5643,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
inp->sctp_ep.default_mtu = 0;
|
||||
sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
|
||||
} else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
|
||||
if (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU) {
|
||||
inp->sctp_ep.default_mtu = paddrp->spp_pathmtu;
|
||||
}
|
||||
inp->sctp_ep.default_mtu = paddrp->spp_pathmtu;
|
||||
sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
|
||||
}
|
||||
if (paddrp->spp_flags & SPP_DSCP) {
|
||||
|
Loading…
Reference in New Issue
Block a user