Index: sys/netpfil/pf/pf_ioctl.c =================================================================== --- sys/netpfil/pf/pf_ioctl.c +++ sys/netpfil/pf/pf_ioctl.c @@ -1557,10 +1557,40 @@ rule->u_src_nodes = counter_u64_fetch(krule->src_nodes); } -static void +static int pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule) { +#ifndef INET + if (rule->af == AF_INET) { + return (EAFNOSUPPORT); + } +#endif /* INET */ +#ifndef INET6 + if (rule->af == AF_INET6) { + return (EAFNOSUPPORT); + break; + } +#endif /* INET6 */ + + if (rule->src.addr.type != PF_ADDR_ADDRMASK && + rule->src.addr.type != PF_ADDR_DYNIFTL && + rule->src.addr.type != PF_ADDR_TABLE) { + return (EINVAL); + } + if (rule->src.addr.p.dyn != NULL) { + return (EINVAL); + } + + if (rule->dst.addr.type != PF_ADDR_ADDRMASK && + rule->dst.addr.type != PF_ADDR_DYNIFTL && + rule->dst.addr.type != PF_ADDR_TABLE) { + return (EINVAL); + } + if (rule->dst.addr.p.dyn != NULL) { + return (EINVAL); + } + bzero(krule, sizeof(*krule)); bcopy(&rule->src, &krule->src, sizeof(rule->src)); @@ -1641,6 +1671,8 @@ krule->set_prio[1] = rule->set_prio[1]; bcopy(&rule->divert, &krule->divert, sizeof(krule->divert)); + + return (0); } static int @@ -1815,26 +1847,13 @@ error = EINVAL; break; } - if (pr->rule.src.addr.p.dyn != NULL || - pr->rule.dst.addr.p.dyn != NULL) { - error = EINVAL; - break; - } -#ifndef INET - if (pr->rule.af == AF_INET) { - error = EAFNOSUPPORT; - break; - } -#endif /* INET */ -#ifndef INET6 - if (pr->rule.af == AF_INET6) { - error = EAFNOSUPPORT; - break; - } -#endif /* INET6 */ rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK); - pf_rule_to_krule(&pr->rule, rule); + error = pf_rule_to_krule(&pr->rule, rule); + if (error != 0) { + free(rule, M_PFRULE); + break; + } if (rule->ifname[0]) kif = pf_kkif_create(M_WAITOK); @@ -2090,20 +2109,12 @@ } if (pcr->action != PF_CHANGE_REMOVE) { -#ifndef INET - if (pcr->rule.af == AF_INET) { - error = EAFNOSUPPORT; - break; - } -#endif /* INET */ -#ifndef INET6 - if (pcr->rule.af == AF_INET6) { - error = EAFNOSUPPORT; + newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK); + error = pf_rule_to_krule(&pcr->rule, newrule); + if (error != 0) { + free(newrule, M_PFRULE); break; } -#endif /* INET6 */ - newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK); - pf_rule_to_krule(&pcr->rule, newrule); if (newrule->ifname[0]) kif = pf_kkif_create(M_WAITOK);