summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2014-10-27 21:51:32 +0000
committermikeb <mikeb@openbsd.org>2014-10-27 21:51:32 +0000
commitc64927a627a49bc68bca443fc24b690fa6bf087d (patch)
treeca4ca0a84bd0618be6aed9d08d9e47e03ff2f0a2
parentEnsure proper separation of grep's options and rcctl options that (diff)
downloadwireguard-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.y24
-rw-r--r--sbin/pfctl/pfctl_parser.c32
-rw-r--r--sbin/pfctl/pfctl_parser.h3
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 *);