diff options
author | 2014-10-27 21:51:32 +0000 | |
---|---|---|
committer | 2014-10-27 21:51:32 +0000 | |
commit | c64927a627a49bc68bca443fc24b690fa6bf087d (patch) | |
tree | ca4ca0a84bd0618be6aed9d08d9e47e03ff2f0a2 | |
parent | Ensure proper separation of grep's options and rcctl options that (diff) | |
download | wireguard-openbsd-c64927a627a49bc68bca443fc24b690fa6bf087d.tar.xz wireguard-openbsd-c64927a627a49bc68bca443fc24b690fa6bf087d.zip |
Fixup incorrect expansion of the networking mask for dynamic interface
specifications under certain circumstances resulting in potentially
elevated access permissions for IPv6 traffic. Reported by sthen@;
ok henning benno sthen
-rw-r--r-- | sbin/pfctl/parse.y | 24 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 32 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 3 |
3 files changed, 50 insertions, 9 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 5c57fdfd02b..e9ff277c1a0 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.640 2014/10/25 03:18:13 lteo Exp $ */ +/* $OpenBSD: parse.y,v 1.641 2014/10/27 21:51:32 mikeb Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -4543,7 +4543,7 @@ expand_rule(struct pf_rule *r, int keeprule, struct node_if *interfaces, char tagname[PF_TAG_NAME_SIZE]; char match_tagname[PF_TAG_NAME_SIZE]; u_int8_t flags, flagset, keep_state; - struct node_host *srch, *dsth; + struct node_host *srch, *dsth, *osrch, *odsth; struct redirspec binat; struct pf_rule rb; int dir = r->direction; @@ -4634,6 +4634,18 @@ expand_rule(struct pf_rule *r, int keeprule, struct node_if *interfaces, r->af, src_host, src_port, dst_host, dst_port, proto->proto); + osrch = odsth = NULL; + if (src_host->addr.type == PF_ADDR_DYNIFTL) { + osrch = src_host; + if ((src_host = gen_dynnode(src_host, r->af)) == NULL) + err(1, "expand_rule: calloc"); + } + if (dst_host->addr.type == PF_ADDR_DYNIFTL) { + odsth = dst_host; + if ((dst_host = gen_dynnode(dst_host, r->af)) == NULL) + err(1, "expand_rule: calloc"); + } + error += check_netmask(src_host, r->af); error += check_netmask(dst_host, r->af); @@ -4784,6 +4796,14 @@ expand_rule(struct pf_rule *r, int keeprule, struct node_if *interfaces, uid, gid, rcv, icmp_type, anchor_call); } + if (osrch && src_host->addr.type == PF_ADDR_DYNIFTL) { + free(src_host); + src_host = osrch; + } + if (odsth && dst_host->addr.type == PF_ADDR_DYNIFTL) { + free(dst_host); + dst_host = odsth; + } )))))))))); if (!keeprule) { diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index e86b3c66078..ca7780b95bf 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.299 2014/10/25 03:18:13 lteo Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.300 2014/10/27 21:51:32 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1243,16 +1243,12 @@ int check_netmask(struct node_host *h, sa_family_t af) { struct node_host *n = NULL; - struct pf_addr *m; + struct pf_addr *m; for (n = h; n != NULL; n = n->next) { if (h->addr.type == PF_ADDR_TABLE) continue; m = &h->addr.v.a.mask; - /* fix up netmask for dynaddr */ - if (af == AF_INET && h->addr.type == PF_ADDR_DYNIFTL && - unmask(m, AF_INET6) > 32) - set_ipmask(n, 32); /* netmasks > 32 bit are invalid on v4 */ if (af == AF_INET && (m->addr32[1] || m->addr32[2] || m->addr32[3])) { @@ -1264,6 +1260,30 @@ check_netmask(struct node_host *h, sa_family_t af) return (0); } +struct node_host * +gen_dynnode(struct node_host *h, sa_family_t af) +{ + struct node_host *n; + struct pf_addr *m; + + if (h->addr.type != PF_ADDR_DYNIFTL) + return (NULL); + + if ((n = calloc(1, sizeof(*n))) == NULL) + return (NULL); + bcopy(h, n, sizeof(*n)); + n->ifname = NULL; + n->next = NULL; + n->tail = NULL; + + /* fix up netmask */ + m = &n->addr.v.a.mask; + if (af == AF_INET && unmask(m, AF_INET6) > 32) + set_ipmask(n, 32); + + return (n); +} + /* interface lookup routines */ struct node_host *iftab; diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 3b957b855e5..ec8af3c5923 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.103 2014/08/23 00:11:03 pelikan Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.104 2014/10/27 21:51:32 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -275,6 +275,7 @@ extern const struct pf_timeout pf_timeouts[]; void set_ipmask(struct node_host *, u_int8_t); int check_netmask(struct node_host *, sa_family_t); int unmask(struct pf_addr *, sa_family_t); +struct node_host *gen_dynnode(struct node_host *, sa_family_t); void ifa_load(void); unsigned int ifa_nametoindex(const char *); char *ifa_indextoname(unsigned int, char *); |