The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=cc68decda316558cc53fadfbb39ac51847f363dd

commit cc68decda316558cc53fadfbb39ac51847f363dd
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-07-07 15:09:58 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2025-07-15 07:55:29 +0000

    pf: Reject rules with invalid port ranges
    
    Ranges where the left boundary is bigger than the right one are always bogus
    as they work like `port any' (`port 34<>12' means "all ports") or in way
    that inverts the rule's action (`pass ... port 34:12' means "pass no port at
    all").
    
    Add checks for all ranges and invalidate those that yield no or all ports.
    
    For this to work on redirections, make pfctl(8) pass the range's type,
    otherwise boundary including ranges are not detected as such;  that is to
    say, `struct pf_pool's `port_op' member was unused in the kernel so far.
    
    `rdr-to' rules with invalid ranges could panic the kernel when hit.
    Reported-by: syzbot+9c309db201f06e39a...@syzkaller.appspotmail.com
    
    OK sashan
    
    Obtained from:  OpenBSD, kn <k...@openbsd.org>, 39c2a1337a
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/netpfil/pf/pf_ioctl.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 016bb1fedef0..3caa0d2e3b11 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2041,6 +2041,19 @@ pf_ioctl_getrules(struct pfioc_rule *pr)
        return (0);
 }
 
+static int
+pf_validate_range(uint8_t op, uint16_t port[2])
+{
+       uint16_t a = ntohs(port[0]);
+       uint16_t b = ntohs(port[1]);
+
+       if ((op == PF_OP_RRG && a > b) ||  /* 34:12,  i.e. none */
+           (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */
+           (op == PF_OP_XRG && a > b))    /* 34<>22, i.e. all */
+               return 1;
+       return 0;
+}
+
 int
 pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
     uint32_t pool_ticket, const char *anchor, const char *anchor_call,
@@ -2060,6 +2073,11 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
 
 #define        ERROUT(x)       ERROUT_FUNCTION(errout, x)
 
+       if (pf_validate_range(rule->src.port_op, rule->src.port))
+               ERROUT(EINVAL);
+       if (pf_validate_range(rule->dst.port_op, rule->dst.port))
+               ERROUT(EINVAL);
+
        if (rule->ifname[0])
                kif = pf_kkif_create(M_WAITOK);
        if (rule->rcv_ifname[0])

Reply via email to