diff options
author | Kevin Steves <stevesk@cvs.openbsd.org> | 2010-03-25 18:37:37 +0000 |
---|---|---|
committer | Kevin Steves <stevesk@cvs.openbsd.org> | 2010-03-25 18:37:37 +0000 |
commit | 5a7624d9b553d73e192281e1ea879503044f14f4 (patch) | |
tree | f1a3543735fdcdcda251bee79b55b03447f8d63d | |
parent | 16c31db9071d140fcee3c54f86eedf11b67766bd (diff) |
be more strict in check_option().
ISC dhclient had a buffer overflow:
http://www.kb.cert.org/vuls/id/410676
and while our dhclient is not vulnerable to that, it got us looking at
how the subnet mask option is handled. this limits specific ip
address options to length 4 in conformance with RFC 2132. discussion
started by william@ and with input from krw@
ok krw@
-rw-r--r-- | sbin/dhclient/dhclient.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 2eca62c46fe..5f5fae7b7c8 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.132 2009/11/12 14:18:45 jsg Exp $ */ +/* $OpenBSD: dhclient.c,v 1.133 2010/03/25 18:37:36 stevesk Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -1958,6 +1958,24 @@ check_option(struct client_lease *l, int option) switch (option) { case DHO_SUBNET_MASK: + case DHO_SWAP_SERVER: + case DHO_BROADCAST_ADDRESS: + case DHO_DHCP_SERVER_IDENTIFIER: + case DHO_ROUTER_SOLICITATION_ADDRESS: + case DHO_DHCP_REQUESTED_ADDRESS: + if (ipv4addrs(opbuf) == 0) { + warning("Invalid IP address in option %s: %s", + dhcp_options[option].name, opbuf); + return (0); + } + if (l->options[option].len != 4) { /* RFC 2132 */ + warning("warning: Only 1 IP address allowed in " + "%s option; length %d, must be 4", + dhcp_options[option].name, + l->options[option].len); + l->options[option].len = 4; + } + return (1); case DHO_TIME_SERVERS: case DHO_NAME_SERVERS: case DHO_ROUTERS: @@ -1967,16 +1985,14 @@ check_option(struct client_lease *l, int option) case DHO_LPR_SERVERS: case DHO_IMPRESS_SERVERS: case DHO_RESOURCE_LOCATION_SERVERS: - case DHO_SWAP_SERVER: - case DHO_BROADCAST_ADDRESS: case DHO_NIS_SERVERS: case DHO_NTP_SERVERS: case DHO_NETBIOS_NAME_SERVERS: case DHO_NETBIOS_DD_SERVER: case DHO_FONT_SERVERS: - case DHO_DHCP_SERVER_IDENTIFIER: - if (!ipv4addrs(opbuf)) { - warning("Invalid IP address in option: %s", opbuf); + if (ipv4addrs(opbuf) == 0) { + warning("Invalid IP address in option %s: %s", + dhcp_options[option].name, opbuf); return (0); } return (1); @@ -2008,7 +2024,6 @@ check_option(struct client_lease *l, int option) case DHO_PERFORM_MASK_DISCOVERY: case DHO_MASK_SUPPLIER: case DHO_ROUTER_DISCOVERY: - case DHO_ROUTER_SOLICITATION_ADDRESS: case DHO_STATIC_ROUTES: case DHO_TRAILER_ENCAPSULATION: case DHO_ARP_CACHE_TIMEOUT: @@ -2020,7 +2035,6 @@ check_option(struct client_lease *l, int option) case DHO_NETBIOS_NODE_TYPE: case DHO_NETBIOS_SCOPE: case DHO_X_DISPLAY_MANAGER: - case DHO_DHCP_REQUESTED_ADDRESS: case DHO_DHCP_LEASE_TIME: case DHO_DHCP_OPTION_OVERLOAD: case DHO_DHCP_MESSAGE_TYPE: |