The branch main has been updated by kp:

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

commit 3524dfd74144b7e9ad43f4317d494bf41645bb45
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-07-08 09:39:25 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2025-07-15 07:55:29 +0000

    pfctl: Fail to parse rules with invalid ranges
    
    This makes pfctl(8) detect bogus ranges (with and without `-n') before
    loading the ruleset and completes the previous commit.
    
    OK sashan sthen
    
    Obtained from:  OpenBSD, kn <k...@openbsd.org>, 123a1e155c
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sbin/pfctl/parse.y | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 4286b6149ac6..a8a165d336fa 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -367,6 +367,7 @@ static struct node_fairq_opts        fairq_opts;
 static struct node_state_opt   *keep_state_defaults = NULL;
 static struct pfctl_watermarks  syncookie_opts;
 
+int             validate_range(uint8_t, uint16_t, uint16_t);
 int             disallow_table(struct node_host *, const char *);
 int             disallow_urpf_failed(struct node_host *, const char *);
 int             disallow_alias(struct node_host *, const char *);
@@ -3825,9 +3826,14 @@ port_item        : portrange                     {
                                err(1, "port_item: calloc");
                        $$->port[0] = $1.a;
                        $$->port[1] = $1.b;
-                       if ($1.t)
+                       if ($1.t) {
                                $$->op = PF_OP_RRG;
-                       else
+                               if (validate_range($$->op, $$->port[0],
+                                   $$->port[1])) {
+                                       yyerror("invalid port range");
+                                       YYERROR;
+                               }
+                       } else
                                $$->op = PF_OP_EQ;
                        $$->next = NULL;
                        $$->tail = $$;
@@ -3844,6 +3850,10 @@ port_item        : portrange                     {
                        $$->port[0] = $2.a;
                        $$->port[1] = $2.b;
                        $$->op = $1;
+                       if (validate_range($$->op, $$->port[0], $$->port[1])) {
+                               yyerror("invalid port range");
+                               YYERROR;
+                       }
                        $$->next = NULL;
                        $$->tail = $$;
                }
@@ -3859,6 +3869,10 @@ port_item        : portrange                     {
                        $$->port[0] = $1.a;
                        $$->port[1] = $3.a;
                        $$->op = $2;
+                       if (validate_range($$->op, $$->port[0], $$->port[1])) {
+                               yyerror("invalid port range");
+                               YYERROR;
+                       }
                        $$->next = NULL;
                        $$->tail = $$;
                }
@@ -5196,6 +5210,19 @@ yyerror(const char *fmt, ...)
        return (0);
 }
 
+int
+validate_range(uint8_t op, uint16_t p1, uint16_t p2)
+{
+       uint16_t a = ntohs(p1);
+       uint16_t b = ntohs(p2);
+
+       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
 disallow_table(struct node_host *h, const char *fmt)
 {
@@ -6018,8 +6045,14 @@ apply_rdr_ports(struct pfctl_rule *r, struct pfctl_pool 
*rpool, struct redirspec
        if (!rs->rport.b && rs->rport.t) {
                rpool->proxy_port[1] = ntohs(rs->rport.a) +
                    (ntohs(r->dst.port[1]) - ntohs(r->dst.port[0]));
-       } else
+       } else {
+               if (validate_range(rs->rport.t, rs->rport.a,
+                   rs->rport.b)) {
+                       yyerror("invalid rdr-to port range");
+                       return (1);
+               }
                r->rdr.proxy_port[1] = ntohs(rs->rport.b);
+       }
 
        if (rs->pool_opts.staticport) {
                yyerror("the 'static-port' option is only valid with nat 
rules");

Reply via email to