Hi,
https://syzkaller.appspot.com/bug?id=a6475751c2856d5ea5586f7120d14db1e00bf253
I think these crashes are caused by an af-to rule that has no
translation address family naf. Preventing such a rule in the
kernel might help.
ok?
bluhm
Index: net/pf_ioctl.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.370
diff -u -p -r1.370 pf_ioctl.c
--- net/pf_ioctl.c 11 Jan 2022 09:00:17 -0000 1.370
+++ net/pf_ioctl.c 24 Jan 2022 12:41:40 -0000
@@ -109,6 +109,7 @@ void pf_trans_set_commit(void);
void pf_pool_copyin(struct pf_pool *, struct pf_pool *);
int pf_validate_range(u_int8_t, u_int16_t[2]);
int pf_rule_copyin(struct pf_rule *, struct pf_rule *);
+int pf_rule_checkaf(struct pf_rule *);
u_int16_t pf_qname2qid(char *, int);
void pf_qid2qname(u_int16_t, char *);
void pf_qid_unref(u_int16_t);
@@ -1347,22 +1348,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
rule = NULL;
break;
}
- switch (rule->af) {
- case 0:
- break;
- case AF_INET:
- break;
-#ifdef INET6
- case AF_INET6:
- break;
-#endif /* INET6 */
- default:
+ if ((error = pf_rule_checkaf(rule))) {
pf_rule_free(rule);
rule = NULL;
- error = EAFNOSUPPORT;
goto fail;
}
-
if (rule->src.addr.type == PF_ADDR_NONE ||
rule->dst.addr.type == PF_ADDR_NONE) {
error = EINVAL;
@@ -1601,23 +1591,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
newrule = NULL;
break;
}
-
- switch (newrule->af) {
- case 0:
- break;
- case AF_INET:
- break;
-#ifdef INET6
- case AF_INET6:
- break;
-#endif /* INET6 */
- default:
- error = EAFNOSUPPORT;
+ if ((error = pf_rule_checkaf(newrule))) {
pf_rule_free(newrule);
newrule = NULL;
goto fail;
}
-
if (newrule->rt && !newrule->direction) {
pf_rule_free(newrule);
error = EINVAL;
@@ -3216,6 +3194,34 @@ pf_rule_copyin(struct pf_rule *from, str
to->set_prio[1] = from->set_prio[1];
return (0);
+}
+
+int
+pf_rule_checkaf(struct pf_rule *r)
+{
+ switch (r->af) {
+ case 0:
+ if (r->rule_flag & PFRULE_AFTO)
+ return EPFNOSUPPORT;
+ break;
+ case AF_INET:
+ if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET6)
+ return EPFNOSUPPORT;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET)
+ return EPFNOSUPPORT;
+ break;
+#endif /* INET6 */
+ default:
+ return EPFNOSUPPORT;
+ }
+
+ if ((r->rule_flag & PFRULE_AFTO) == 0 && r->naf != 0)
+ return EPFNOSUPPORT;
+
+ return 0;
}
int