diff options
author | Kristof Provost <kp@FreeBSD.org> | 2021-02-13 15:31:52 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2021-02-14 11:07:31 +0000 |
commit | 5e42cb139fc17f165c9c93ac97069dc7770490e2 (patch) | |
tree | aa85016321fdd604492dfbffc6a900cbfe09b35a | |
parent | ed782b9f5a7a05debe944a33b4ac9e5629a95803 (diff) | |
download | src-5e42cb139fc17f165c9c93ac97069dc7770490e2.tar.gz src-5e42cb139fc17f165c9c93ac97069dc7770490e2.zip |
pf: Slightly relax pf_rule_addr validation
Ensure we don't reject no-route / urpf-failed addresses.
PR: 253479
Reported by: michal AT microwave.sk
Revied by: donner@
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D28650
-rw-r--r-- | sys/netpfil/pf/pf_ioctl.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 644a091808cd..edc8443dcc0a 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -1558,8 +1558,32 @@ pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule) } static int +pf_check_rule_addr(const struct pf_rule_addr *addr) +{ + + switch (addr->addr.type) { + case PF_ADDR_ADDRMASK: + case PF_ADDR_NOROUTE: + case PF_ADDR_DYNIFTL: + case PF_ADDR_TABLE: + case PF_ADDR_URPFFAILED: + case PF_ADDR_RANGE: + break; + default: + return (EINVAL); + } + + if (addr->addr.p.dyn != NULL) { + return (EINVAL); + } + + return (0); +} + +static int pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule) { + int ret; #ifndef INET if (rule->af == AF_INET) { @@ -1572,23 +1596,12 @@ pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule) } #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); - } + ret = pf_check_rule_addr(&rule->src); + if (ret != 0) + return (ret); + ret = pf_check_rule_addr(&rule->dst); + if (ret != 0) + return (ret); bzero(krule, sizeof(*krule)); |