mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-22 01:49:35 +00:00
Check for valid prefixes in configuration.
See RT ticket #16944 for more information.
This commit is contained in:
parent
e847f9833c
commit
9b21e73e3c
3
RELNOTES
3
RELNOTES
@ -54,6 +54,9 @@ suggested fixes to <dhcp-users@isc.org>.
|
||||
|
||||
Changes since 4.0.0a1
|
||||
|
||||
- Invalid CIDR representation for IPv6 subnets or ranges now checked
|
||||
for when loading configuration.
|
||||
|
||||
- Compilation on HP/UX has been repaired. The changes should generally
|
||||
apply to any architecture that supplies SIOCGLIFCONF but does not
|
||||
use 'struct lifconf' structures to pass values.
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: inet.c,v 1.13 2007/05/19 19:16:24 dhankins Exp $ Copyright (c) 2004,2005,2007 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: inet.c,v 1.14 2007/06/19 17:06:03 shane Exp $ Copyright (c) 2004,2005,2007 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@ -297,6 +297,66 @@ addr_and(struct iaddr *result, const struct iaddr *a1, const struct iaddr *a2) {
|
||||
return !all_zero;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a bitmask of the given length is valid for the address.
|
||||
* This is not the case if any bits longer than the bitmask are 1.
|
||||
*
|
||||
* So, this is valid:
|
||||
*
|
||||
* 127.0.0.0/8
|
||||
*
|
||||
* But this is not:
|
||||
*
|
||||
* 127.0.0.1/8
|
||||
*
|
||||
* Because the final ".1" would get masked out by the /8.
|
||||
*/
|
||||
isc_boolean_t
|
||||
is_cidr_mask_valid(const struct iaddr *addr, int bits) {
|
||||
int zero_bits;
|
||||
int zero_bytes;
|
||||
int i;
|
||||
char byte;
|
||||
int shift_bits;
|
||||
|
||||
/*
|
||||
* Check our bit boundaries.
|
||||
*/
|
||||
if (bits < 0) {
|
||||
return ISC_FALSE;
|
||||
}
|
||||
if (bits > (addr->len * 8)) {
|
||||
return ISC_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out how many low-order bits need to be zero.
|
||||
*/
|
||||
zero_bits = (addr->len * 8) - bits;
|
||||
zero_bytes = zero_bits / 8;
|
||||
|
||||
/*
|
||||
* Check to make sure the low-order bytes are zero.
|
||||
*/
|
||||
for (i=1; i<=zero_bytes; i++) {
|
||||
if (addr->iabuf[addr->len-i] != 0) {
|
||||
return ISC_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Look to see if any bits not in right-hand bytes are
|
||||
* non-zero, by making a byte that has these bits set to zero
|
||||
* comparing to the original byte. If these two values are
|
||||
* equal, then the right-hand bits are zero, and we are
|
||||
* happy.
|
||||
*/
|
||||
shift_bits = zero_bits % 8;
|
||||
if (shift_bits == 0) return ISC_TRUE;
|
||||
byte = addr->iabuf[addr->len-zero_bytes-1];
|
||||
return (((byte >> shift_bits) << shift_bits) == byte);
|
||||
}
|
||||
|
||||
/*
|
||||
* range2cidr
|
||||
*
|
||||
|
@ -2321,6 +2321,7 @@ int addr_or(struct iaddr *result,
|
||||
const struct iaddr *a1, const struct iaddr *a2);
|
||||
int addr_and(struct iaddr *result,
|
||||
const struct iaddr *a1, const struct iaddr *a2);
|
||||
isc_boolean_t is_cidr_mask_valid(const struct iaddr *addr, int bits);
|
||||
isc_result_t range2cidr(struct iaddrcidrnetlist **result,
|
||||
const struct iaddr *lo, const struct iaddr *hi);
|
||||
isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result);
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: confpars.c,v 1.167 2007/06/08 14:58:20 dhankins Exp $ Copyright (c) 2004-2007 Internet Systems Consortium. All rights reserved.\n";
|
||||
"$Id: confpars.c,v 1.168 2007/06/19 17:06:03 shane Exp $ Copyright (c) 2004-2007 Internet Systems Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@ -2640,6 +2640,12 @@ parse_subnet6_declaration(struct parse *cfile, struct shared_network *share) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_cidr_mask_valid(&subnet->net, subnet->prefix_len)) {
|
||||
parse_warn(cfile, "New subnet mask too short.");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a netmask.
|
||||
*/
|
||||
@ -3703,6 +3709,11 @@ parse_address_range6(struct parse *cfile, struct group *group) {
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
if (!is_cidr_mask_valid(&lo, bits)) {
|
||||
parse_warn(cfile, "network mask too short");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
add_ipv6_pool_to_shared_network(share, &lo, bits);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user