pf: improve SCTP validation

As per RFC5061 "4.2.  New Parameter Types" the add/delete IP address
parameters (0xc001, 0xc002) may not be present in an INIT or INIT-ACK
chunk. They are only allowed to be present in an ASCONF chunk.

This also prevents unbounded recursion while parsing an SCTP packet.

Approved by:	so
Security:	FreeBSD-SA-26:14.pf
Security:	CVE-2026-7164
PR:		294799
Reported by:	Igor Gabriel Sousa e Souza
Sponsored by:	Orange Business Services
This commit is contained in:
Kristof Provost 2026-04-26 11:34:55 +02:00 committed by Franco Fichtner
parent d9320cd313
commit 2ef27363b5

View file

@ -6647,7 +6647,7 @@ again:
static int
pf_multihome_scan(struct mbuf *m, int start, int len, struct pf_pdesc *pd,
struct pfi_kkif *kif, int op)
struct pfi_kkif *kif, int op, bool asconf)
{
int off = 0;
struct pf_sctp_multihome_job *job;
@ -6750,13 +6750,16 @@ pf_multihome_scan(struct mbuf *m, int start, int len, struct pf_pdesc *pd,
int ret;
struct sctp_asconf_paramhdr ah;
if (asconf)
return (PF_DROP);
if (!pf_pull_hdr(m, start + off, &ah, sizeof(ah),
NULL, NULL, pd->af))
return (PF_DROP);
ret = pf_multihome_scan(m, start + off + sizeof(ah),
ntohs(ah.ph.param_length) - sizeof(ah), pd, kif,
SCTP_ADD_IP_ADDRESS);
SCTP_ADD_IP_ADDRESS, true);
if (ret != PF_PASS)
return (ret);
break;
@ -6765,12 +6768,15 @@ pf_multihome_scan(struct mbuf *m, int start, int len, struct pf_pdesc *pd,
int ret;
struct sctp_asconf_paramhdr ah;
if (asconf)
return (PF_DROP);
if (!pf_pull_hdr(m, start + off, &ah, sizeof(ah),
NULL, NULL, pd->af))
return (PF_DROP);
ret = pf_multihome_scan(m, start + off + sizeof(ah),
ntohs(ah.ph.param_length) - sizeof(ah), pd, kif,
SCTP_DEL_IP_ADDRESS);
SCTP_DEL_IP_ADDRESS, true);
if (ret != PF_PASS)
return (ret);
break;
@ -6792,7 +6798,8 @@ pf_multihome_scan_init(struct mbuf *m, int start, int len, struct pf_pdesc *pd,
start += sizeof(struct sctp_init_chunk);
len -= sizeof(struct sctp_init_chunk);
return (pf_multihome_scan(m, start, len, pd, kif, SCTP_ADD_IP_ADDRESS));
return (pf_multihome_scan(m, start, len, pd, kif, SCTP_ADD_IP_ADDRESS,
false));
}
int
@ -6802,7 +6809,8 @@ pf_multihome_scan_asconf(struct mbuf *m, int start, int len,
start += sizeof(struct sctp_asconf_chunk);
len -= sizeof(struct sctp_asconf_chunk);
return (pf_multihome_scan(m, start, len, pd, kif, SCTP_ADD_IP_ADDRESS));
return (pf_multihome_scan(m, start, len, pd, kif, SCTP_ADD_IP_ADDRESS,
false));
}
int