From 01b88ac323c1ca4b2965e2dc60150fa1e2196854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Tue, 30 Nov 2021 12:00:34 +0100 Subject: [PATCH] checkpolicy: warn on bogus IP address or netmask in nodecon statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Warn if the netmask is not contiguous or the address has host bits set, e.g.: 127.0.0.0 255.255.245.0 127.0.0.1 255.255.255.0 Signed-off-by: Christian Göttsche --- checkpolicy/policy_define.c | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index d3eb6111..b2ae3263 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -5290,6 +5290,14 @@ int define_ipv4_node_context() goto out; } + if (mask.s_addr != 0 && ((~mask.s_addr + 1) & ~mask.s_addr) != 0) { + yywarn("ipv4 mask is not contiguous"); + } + + if ((~mask.s_addr & addr.s_addr) != 0) { + yywarn("host bits in ipv4 address set"); + } + newc = malloc(sizeof(ocontext_t)); if (!newc) { yyerror("out of memory"); @@ -5325,6 +5333,40 @@ out: return rc; } +static int ipv6_is_mask_contiguous(const struct in6_addr *mask) +{ + int filled = 1; + unsigned i; + + for (i = 0; i < 16; i++) { + if ((((~mask->s6_addr[i] & 0xFF) + 1) & (~mask->s6_addr[i] & 0xFF)) != 0) { + return 0; + } + if (!filled && mask->s6_addr[i] != 0) { + return 0; + } + + if (filled && mask->s6_addr[i] != 0xFF) { + filled = 0; + } + } + + return 1; +} + +static int ipv6_has_host_bits_set(const struct in6_addr *addr, const struct in6_addr *mask) +{ + unsigned i; + + for (i = 0; i < 16; i++) { + if ((addr->s6_addr[i] & ~mask->s6_addr[i]) != 0) { + return 1; + } + } + + return 0; +} + int define_ipv6_node_context(void) { char *id; @@ -5376,6 +5418,14 @@ int define_ipv6_node_context(void) goto out; } + if (!ipv6_is_mask_contiguous(&mask)) { + yywarn("ipv6 mask is not contiguous"); + } + + if (ipv6_has_host_bits_set(&addr, &mask)) { + yywarn("host bits in ipv6 address set"); + } + newc = malloc(sizeof(ocontext_t)); if (!newc) { yyerror("out of memory");