fix zero division found by syzkaller. The sanity checks in pf(4) ioctls
authorsashan <sashan@openbsd.org>
Thu, 16 Dec 2021 02:01:59 +0000 (02:01 +0000)
committersashan <sashan@openbsd.org>
Thu, 16 Dec 2021 02:01:59 +0000 (02:01 +0000)
are not powerful enough to detect invalid port ranges (or even invalid
rules). syzkaller does not use pfctl(8), it uses ioctl(2) to pass some
random chunk of memory as a rule to pf(4). Fix adds explicit check
for 0 divider to pf_get_transaddr(). It should make syzkaller happy
without disturbing anyone else.

OK gnezdo@

Reported-by: syzbot+d1f00da48fa717e171f3@syzkaller.appspotmail.com
sys/net/pf_lb.c

index 2f74762..65f70ef 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pf_lb.c,v 1.68 2020/12/12 22:59:21 jan Exp $ */
+/*     $OpenBSD: pf_lb.c,v 1.69 2021/12/16 02:01:59 sashan Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -706,11 +706,12 @@ pf_get_transaddr(struct pf_rule *r, struct pf_pdesc *pd,
                nport = 0;
                if (r->rdr.proxy_port[1]) {
                        u_int32_t       tmp_nport;
+                       u_int16_t       div;
 
-                       tmp_nport = ((ntohs(pd->ndport) -
-                           ntohs(r->dst.port[0])) %
-                           (r->rdr.proxy_port[1] -
-                           r->rdr.proxy_port[0] + 1)) +
+                       div = r->rdr.proxy_port[1] - r->rdr.proxy_port[0] + 1;
+                       div = (div == 0) ? 1 : div;
+
+                       tmp_nport = ((ntohs(pd->ndport) - ntohs(r->dst.port[0])) % div) +
                            r->rdr.proxy_port[0];
 
                        /* wrap around if necessary */