The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=a46974905b0effca7bb2fdfb4b19360f6e9d8897
commit a46974905b0effca7bb2fdfb4b19360f6e9d8897 Author: Kristof Provost <k...@freebsd.org> AuthorDate: 2025-07-16 14:37:44 +0000 Commit: Kristof Provost <k...@freebsd.org> CommitDate: 2025-07-23 13:35:45 +0000 pf: Make pf(4) more paranoid about IGMP/MLP messages. MLD/IGMP messages with ttl other than 1 will be discarded. Also MLD messages with other than link-local source address will be discarded. IGMP messages with destination address other than multicast class will be discarded. feedback and OK bluhm@, cluadio@ Obtained from: OpenBSD, sashan <sas...@openbsd.org>, 5f7837b6d7 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 0a951815656e..20641fbcbce4 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -9872,8 +9872,16 @@ pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason) pd->off += hlen; pd->proto = h->ip_p; /* IGMP packets have router alert options, allow them */ - if (pd->proto == IPPROTO_IGMP) + if (pd->proto == IPPROTO_IGMP) { + /* According to RFC 1112 ttl must be set to 1. */ + if ((h->ip_ttl != 1) || + !IN_MULTICAST(ntohl(h->ip_dst.s_addr))) { + DPFPRINTF(PF_DEBUG_MISC, ("Invalid IGMP\n")); + REASON_SET(reason, PFRES_IPOPTIONS); + return (PF_DROP); + } pd->badopts &= ~PF_OPT_ROUTER_ALERT; + } /* stop walking over non initial fragments */ if ((h->ip_off & htons(IP_OFFMASK)) != 0) return (PF_PASS); @@ -10113,6 +10121,19 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) case MLD_LISTENER_REPORT: case MLD_LISTENER_DONE: case MLDV2_LISTENER_REPORT: + /* + * According to RFC 2710 all MLD messages are + * sent with hop-limit (ttl) set to 1, and link + * local source address. If either one is + * missing then MLD message is invalid and + * should be discarded. + */ + if ((h->ip6_hlim != 1) || + !IN6_IS_ADDR_LINKLOCAL(&h->ip6_src)) { + DPFPRINTF(PF_DEBUG_MISC, ("Invalid MLD\n")); + REASON_SET(reason, PFRES_IPOPTIONS); + return (PF_DROP); + } pd->badopts &= ~PF_OPT_ROUTER_ALERT; break; }