Hello community,
here is the log from the commit of package dhcpcd for openSUSE:11.3
checked in at Wed Apr 6 16:59:37 CEST 2011.
--------
--- old-versions/11.3/all/dhcpcd/dhcpcd.changes 2010-07-01 14:05:24.000000000 +0200
+++ 11.3/dhcpcd/dhcpcd.changes 2011-03-31 15:49:46.000000000 +0200
@@ -1,0 +2,16 @@
+Thu Mar 31 13:47:05 UTC 2011 - varkoly@novell.com
+
+- bnc#675052 - discard string options such as host and domain names
+ containing disallowed characters or beeing too long. This proctive
+ patch limits root-path to a-zA-Z0-9, #%+-_:.,@~/\[]= and a space
+ (CVE-2011-0997).
+- fixed to read netbios scope from info file as string
+- bnc#668194 - handle packets with xen partial UDP checksums
+- bnc#657402 - send renew messages as unicast directly to the server
+
+-------------------------------------------------------------------
+Tue Nov 30 14:15:08 UTC 2010 - varkoly@novell.com
+
+- bnc#654649 - dhcpcd ignores -G (--nogateway) option and sets default route
+
+-------------------------------------------------------------------
Package does not exist at destination yet. Using Fallback old-versions/11.3/all/dhcpcd
Destination is old-versions/11.3/UPDATES/all/dhcpcd
calling whatdependson for 11.3-i586
New:
----
dhcpcd-3.2.3-option-checks.diff
dhcpcd-3.2.3-renew-unicast.diff
dhcpcd-3.2.3-xen-checksum.diff
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ dhcpcd.spec ++++++
--- /var/tmp/diff_new_pack.29gwPl/_old 2011-04-06 16:59:05.000000000 +0200
+++ /var/tmp/diff_new_pack.29gwPl/_new 2011-04-06 16:59:05.000000000 +0200
@@ -1,7 +1,7 @@
#
-# spec file for package dhcpcd (Version 3.2.3)
+# spec file for package dhcpcd
#
-# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
Name: dhcpcd
Version: 3.2.3
-Release: 56
+Release: 61.<RELEASE2>
Summary: A DHCP Client Daemon
Url: http://developer.berlios.de/projects/dhcpcd/
#Source: http://prdownload.berlios.de/dhcpcd/dhcpcd-3.2.3.tar.bz2
@@ -46,6 +46,9 @@
Patch17: bnc#564441.diff
Patch18: bnc#577402.diff
Patch19: bnc#579438.diff
+Patch20: dhcpcd-3.2.3-renew-unicast.diff
+Patch21: dhcpcd-3.2.3-xen-checksum.diff
+Patch22: dhcpcd-3.2.3-option-checks.diff
License: GPLv2+
Group: Productivity/Networking/Boot/Clients
Provides: dhcp_client
@@ -87,6 +90,9 @@
%patch17 -p0
%patch18 -p0
%patch19 -p0
+%patch20 -p0
+%patch21 -p0
+%patch22 -p0
cp %{S:1} .
cp %{S:3} .
++++++ dhcpcd-3.2.3-more-params.diff ++++++
--- /var/tmp/diff_new_pack.29gwPl/_old 2011-04-06 16:59:05.000000000 +0200
+++ /var/tmp/diff_new_pack.29gwPl/_new 2011-04-06 16:59:05.000000000 +0200
@@ -186,7 +186,7 @@
+ else if (strcmp (var, "LOGSERVER") == 0)
+ dhcp->logservers = parse_addresses (value, "LOGSERVER");
+ else if (strcmp (var, "NETBIOSSCOPE") == 0)
-+ parse_uint (&dhcp->netbiosscope, value, "NETBIOSSCOPE");
++ dhcp->netbiosscope = xstrdup (value);
+ else if (strcmp (var, "NETBIOSNAMESERVER") == 0)
+ dhcp->netbiosnameservers = parse_addresses (value, "NETBIOSNAMESERVER");
+ else if (strcmp (var, "NETBIOSDDSERVER") == 0)
++++++ dhcpcd-3.2.3-netconfig.diff ++++++
--- /var/tmp/diff_new_pack.29gwPl/_old 2011-04-06 16:59:05.000000000 +0200
+++ /var/tmp/diff_new_pack.29gwPl/_new 2011-04-06 16:59:05.000000000 +0200
@@ -118,17 +118,7 @@
options->timeout = DEFAULT_TIMEOUT;
gethostname (options->hostname, sizeof (options->hostname));
-@@ -362,7 +364,8 @@
- }
- break;
- case 'G':
-- options->dogateway = false;
-+ if(!options->netconfig)
-+ options->dogateway = false;
- break;
- case 'H':
- options->dohostname++;
-@@ -410,9 +413,19 @@
+@@ -410,9 +413,18 @@
case 'Y':
options->donis = false;
break;
@@ -144,7 +134,6 @@
+ options->donis = false;
+ options->donisdom = false;
+ options->dontp = false;
-+ options->dogateway = true;
+ options->netconfig = true;
+ options->script = "/etc/sysconfig/network/scripts/dhcpcd-hook";
+ break;
++++++ dhcpcd-3.2.3-option-checks.diff ++++++
--- configure.c
+++ configure.c
@@ -540,7 +540,7 @@ static char *lookuphostname (char *hostname, const dhcp_t *dhcp,
char *addr;
struct addrinfo hints;
struct addrinfo *res = NULL;
- int result;
+ int result, check;
logger (LOG_DEBUG, "Looking up hostname via DNS");
addr = xmalloc (sizeof (char) * NI_MAXHOST);
@@ -565,9 +565,10 @@ static char *lookuphostname (char *hostname, const dhcp_t *dhcp,
result = getaddrinfo (addr, "0", &hints, &res);
if (res)
freeaddrinfo (res);
- if (result == 0)
+ check = check_domain_name(addr, strlen(addr), 0);
+ if (result == 0 || check != 0)
logger (LOG_ERR, "malicious PTR record detected");
- if (result == 0 || ! *addr) {
+ if (result == 0 || ! *addr || check != 0) {
free (addr);
return (NULL);
}
@@ -842,12 +843,12 @@ int configure (const options_t *options, interface_t *iface,
exec_script (options->script, iface->infofile, "up");
curhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
- *curhostname = '\0';
+ memset(curhostname, 0, MAXHOSTNAMELEN);
- gethostname (curhostname, MAXHOSTNAMELEN);
+ gethostname (curhostname, MAXHOSTNAMELEN - 1);
+ curhostname[MAXHOSTNAMELEN - 1] = '\0';
if (options->dohostname ||
- strlen (curhostname) == 0 ||
- strcmp (curhostname, "(none)") == 0 ||
+ check_domain_name(curhostname, strlen (curhostname), 0) != 0 ||
strcmp (curhostname, "localhost") == 0)
{
newhostname = xmalloc (sizeof (char) * MAXHOSTNAMELEN);
--- dhcp.c
+++ dhcp.c
@@ -41,6 +41,8 @@
#include
#include
#include
+#include
+#include
#include "config.h"
@@ -316,6 +318,7 @@ ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
*p++ = DHCP_LOGSERVER;
*p++ = DHCP_NETBIOSNAMESERVER;
*p++ = DHCP_NETBIOSDDSERVER;
+ *p++ = DHCP_NETBIOSNODETYPE;
*p++ = DHCP_NETBIOSSCOPE;
}
@@ -646,6 +649,106 @@ static struct route_head *decode_routers (const unsigned char *data, int length)
return (head);
}
+int check_domain_name(const char *ptr, size_t len, int dots)
+{
+ const char *p;
+
+ /* not empty or complete length not over 255 characters */
+ if (len == 0 || len >= 256)
+ return -1;
+
+ /* consists of [[:alnum:]-]+ labels separated by [.] */
+ /* a [_] is against RFC but seems to be "widely used"... */
+ for (p=ptr; *p && len-- > 0; p++) {
+ if ( *p == '-' || *p == '_') {
+ /* not allowed at begin or end of a label */
+ if ((p - ptr) == 0 || len == 0 || p[1] == '.')
+ return -1;
+ } else
+ if ( *p == '.') {
+ /* each label has to be 1-63 characters;
+ we allow [.] at the end ('foo.bar.') */
+ ptrdiff_t d = p - ptr;
+ if( d <= 0 || d >= 64)
+ return -1;
+ ptr = p + 1; /* jump to the next label */
+ if(dots > 0 && len > 0)
+ dots--;
+ } else
+ if ( !isalnum((unsigned char)*p)) {
+ /* also numbers at the begin are fine */
+ return -1;
+ }
+ }
+ return dots ? -1 : 0;
+}
+
+int check_domain_name_list(const char *ptr, size_t len, int dots)
+{
+ const char *p;
+ int ret = -1; /* at least one needed */
+
+ if (!ptr || !len)
+ return -1;
+
+ for (p=ptr; *p && len > 0; p++, len--) {
+ if (*p != ' ')
+ continue;
+ if (p > ptr) {
+ if (check_domain_name(ptr, p - ptr, dots) != 0)
+ return -1;
+ ret = 0;
+ }
+ ptr = p + 1;
+ }
+ if (p > ptr)
+ return check_domain_name(ptr, p - ptr, dots);
+ else
+ return ret;
+}
+
+int check_dhcp_option(unsigned char option, const char *ptr, size_t len)
+{
+ if( !ptr)
+ return -1;
+
+ switch (option) {
+ case DHCP_NETBIOSNODETYPE:
+ if(len == 1 && ((int)*ptr == 1 || (int)*ptr == 2 ||
+ (int)*ptr == 4 || (int)*ptr == 8))
+ return 0;
+ break;
+ case DHCP_HOSTNAME:
+ case DHCP_DNSDOMAIN:
+ case DHCP_NISDOMAIN:
+ case DHCP_NETBIOSSCOPE:
+ return check_domain_name(ptr, len, 0);
+ break;
+ case DHCP_SIPSERVER:
+ case DHCP_DNSSEARCH:
+ return check_domain_name_list(ptr, len, 0);
+ break;
+ case DHCP_ROOTPATH:
+ if( len == 0)
+ return -1;
+ for (; *ptr && len-- > 0; ptr++) {
+ if( !(isalnum((unsigned char)*ptr) ||
+ *ptr == '#' || *ptr == '%' ||
+ *ptr == '+' || *ptr == '-' ||
+ *ptr == '_' || *ptr == ':' ||
+ *ptr == '.' || *ptr == ',' ||
+ *ptr == '@' || *ptr == '~' ||
+ *ptr == '\\' || *ptr == '/' ||
+ *ptr == '[' || *ptr == ']' ||
+ *ptr == '=' || *ptr == ' '))
+ return -1;
+ }
+ return 0;
+ break;
+ }
+ return 0;
+}
+
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
{
const unsigned char *p = message->options;
@@ -676,8 +779,16 @@ int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
dhcp->leasedfrom = tv.tv_sec;
dhcp->frominfo = false;
dhcp->address.s_addr = message->yiaddr;
- strlcpy (dhcp->servername, (char *) message->servername,
- sizeof (dhcp->servername));
+ if (message->servername[0] != '\0' &&
+ check_domain_name((const char *)message->servername,
+ strlen((const char *)message->servername), 0) != 0)
+ {
+ logger (LOG_ERR, "suspect value in SERVERNAME - discarded");
+ dhcp->servername[0] = '\0';
+ } else {
+ strlcpy (dhcp->servername, (char *) message->servername,
+ sizeof (dhcp->servername));
+ }
#define LEN_ERR \
{ \
@@ -798,10 +909,20 @@ parse_start:
memcpy (_var, p, (size_t) length); \
memset (_var + length, 0, 1); \
}
+#define CHECKOPT(_opt,_var) \
+ if(check_dhcp_option(_opt, (const char *)p, length) != 0) { \
+ logger (LOG_ERR, "suspect value in option %s - discarded", #_opt); \
+ if (_var) free (_var); \
+ _var = NULL; \
+ }
case DHCP_HOSTNAME:
+ CHECKOPT (DHCP_HOSTNAME, dhcp->hostname)
+ else
GETSTR (dhcp->hostname);
break;
case DHCP_DNSDOMAIN:
+ CHECKOPT (DHCP_DNSDOMAIN, dhcp->dnsdomain)
+ else
GETSTR (dhcp->dnsdomain);
break;
case DHCP_MESSAGE:
@@ -809,18 +930,30 @@ parse_start:
break;
#ifdef ENABLE_INFO
case DHCP_ROOTPATH:
+ CHECKOPT (DHCP_ROOTPATH, dhcp->rootpath)
+ else
GETSTR (dhcp->rootpath);
break;
#endif
#ifdef ENABLE_NIS
case DHCP_NISDOMAIN:
+ CHECKOPT (DHCP_NISDOMAIN, dhcp->nisdomain)
+ else
GETSTR (dhcp->nisdomain);
break;
#endif
case DHCP_NETBIOSNODETYPE:
- GETSTR (dhcp->netbiosnodetype);
+ CHECKOPT (DHCP_NETBIOSNODETYPE, dhcp->netbiosnodetype)
+ else {
+ if(dhcp->netbiosnodetype)
+ free(dhcp->netbiosnodetype);
+ dhcp->netbiosnodetype = xmalloc ((size_t)length + 1);
+ snprintf(dhcp->netbiosnodetype, length + 1, "%d", (int)*p);
+ }
break;
case DHCP_NETBIOSSCOPE:
+ CHECKOPT (DHCP_NETBIOSSCOPE, dhcp->netbiosscope)
+ else
GETSTR (dhcp->netbiosscope);
break;
@@ -863,11 +996,21 @@ parse_start:
case DHCP_DNSSEARCH:
MIN_LENGTH (1);
free (dhcp->dnssearch);
+ dhcp->dnssearch = NULL;
len = decode_search (p, length, NULL);
if (len > 0) {
- dhcp->dnssearch = xmalloc (len);
- decode_search (p, length,
- dhcp->dnssearch);
+ char *str = xmalloc (len);
+ decode_search (p, length, str);
+ if (check_dhcp_option(DHCP_DNSSEARCH,
+ str, len - 1) != 0) {
+ logger (LOG_ERR,
+ "suspect value in "
+ "option %s - discarded",
+ "DHCP_DNSSEARCH");
+ free(str);
+ } else {
+ dhcp->dnssearch = str;
+ }
}
break;
@@ -885,8 +1028,22 @@ parse_start:
#ifdef ENABLE_INFO
case DHCP_SIPSERVER:
- free (dhcp->sipservers);
- dhcp->sipservers = decode_sipservers (p,length);
+ if(dhcp->sipservers)
+ free (dhcp->sipservers);
+ dhcp->sipservers = NULL;
+ {
+ char *str = decode_sipservers (p,length);
+ if(check_dhcp_option(DHCP_SIPSERVER,
+ str, strlen(str)) != 0) {
+ logger (LOG_ERR,
+ "suspect value in "
+ "option %s - discarded",
+ "DHCP_SIPSERVER");
+ free(str);
+ } else {
+ dhcp->sipservers = str;
+ }
+ }
break;
#endif
@@ -922,6 +1079,7 @@ parse_start:
#undef LENGTH
#undef MIN_LENGTH
#undef MULT_LENGTH
+#undef CHECKOPT
default:
logger (LOG_DEBUG,
--- dhcp.h
+++ dhcp.h
@@ -252,4 +252,8 @@ ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
void free_dhcp (dhcp_t *dhcp);
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message);
+int check_dhcp_option(unsigned char option, const char *ptr, size_t len);
+int check_domain_name(const char *ptr, size_t len, int dots);
+int check_domain_name_list(const char *ptr, size_t len, int dots);
+
#endif
--- dhcpcd.c
+++ dhcpcd.c
@@ -182,8 +182,10 @@ int main(int argc, char **argv)
options->netconfig = false;
options->timeout = DEFAULT_TIMEOUT;
- gethostname (options->hostname, sizeof (options->hostname));
- if (strcmp (options->hostname, "(none)") == 0 ||
+ memset (options->hostname, 0, sizeof (options->hostname));
+ gethostname (options->hostname, sizeof (options->hostname) - 1);
+ options->hostname[sizeof (options->hostname) - 1] = '\0';
+ if (check_domain_name(options->hostname, strlen(options->hostname), 0) != 0 ||
strcmp (options->hostname, "localhost") == 0)
memset (options->hostname, 0, sizeof (options->hostname));
@@ -232,6 +234,9 @@ int main(int argc, char **argv)
"`%s' too long for HostName string, max is %d",
optarg, MAXHOSTNAMELEN);
goto abort;
+ } else if(check_domain_name(optarg, strlen(optarg), 0) != 0) {
+ logger (LOG_ERR, "suspect string in hostname argument");
+ goto abort;
} else
strlcpy (options->hostname, optarg,
sizeof (options->hostname));
++++++ dhcpcd-3.2.3-renew-unicast.diff ++++++
--- dhcp.c
+++ dhcp.c
@@ -333,6 +333,22 @@ ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
message_length = p - m;
+ if (to.s_addr && to.s_addr != INADDR_BROADCAST) {
+ struct sockaddr_in sin_to;
+
+ memset(&sin_to, 0, sizeof(sin_to));
+ sin_to.sin_family = AF_INET;
+ sin_to.sin_addr.s_addr = to.s_addr;
+ sin_to.sin_port = htons(DHCP_SERVER_PORT);
+
+ logger (LOG_DEBUG, "sending %s with xid 0x%x to %s",
+ dhcp_message (type), xid, inet_ntoa(to));
+
+ return sendto(iface->listen_fd,
+ (unsigned char *) message, message_length,
+ 0, (struct sockaddr *)&sin_to, sizeof(sin_to));
+ }
+
packet = xzalloc (sizeof (*packet));
make_dhcp_packet (packet, (unsigned char *) message, message_length,
from, to);
@@ -340,6 +356,7 @@ ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
logger (LOG_DEBUG, "sending %s with xid 0x%x",
dhcp_message (type), xid);
+
retval = send_packet (iface, ETHERTYPE_IP, (unsigned char *) packet,
message_length +
sizeof (packet->ip) + sizeof (packet->udp));
--- socket.c
+++ socket.c
@@ -461,8 +461,8 @@ int open_socket (interface_t *iface, int protocol)
/* We need to bind to a port, otherwise Linux generate ICMP messages
* that cannot contect the port when we have an address.
- * We don't actually use this fd at all, instead using our packet
- * filter socket. */
+ * We actually use this fd for unicast messages only, otherwise we're
+ * using our packet filter socket. So read it as udp_fd ... */
if (iface->listen_fd == -1 && protocol == ETHERTYPE_IP) {
if ((fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
logger (LOG_ERR, "socket: %s", strerror (errno));
++++++ dhcpcd-3.2.3-xen-checksum.diff ++++++
--- socket.c
+++ socket.c
@@ -48,7 +48,8 @@
# include
#elif __linux__
# include
-# include
+# include
+/* # include */
# define bpf_insn sock_filter
#endif
@@ -202,7 +203,7 @@ void make_dhcp_packet(struct udp_dhcp_packet *packet,
ip->ip_sum = checksum ((unsigned char *) ip, sizeof (*ip));
}
-static int valid_dhcp_packet (unsigned char *data)
+static int valid_dhcp_packet (unsigned char *data, int nocsum)
{
union
{
@@ -242,7 +243,7 @@ static int valid_dhcp_packet (unsigned char *data)
memcpy (&d.packet->ip.ip_src, &source, sizeof (d.packet->ip.ip_src));
memcpy (&d.packet->ip.ip_dst, &dest, sizeof (d.packet->ip.ip_dst));
d.packet->ip.ip_len = d.packet->udp.uh_ulen;
- if (udpsum && udpsum != checksum (d.data, bytes)) {
+ if (!nocsum && udpsum && udpsum != checksum (d.data, bytes)) {
logger (LOG_ERR, "bad UDP checksum, ignoring");
retval = -1;
}
@@ -409,7 +410,7 @@ ssize_t get_packet (const interface_t *iface, unsigned char *data,
memcpy (data, payload, len);
have_data = true;
} else {
- if (valid_dhcp_packet (payload) >= 0) {
+ if (valid_dhcp_packet (payload, 0) >= 0) {
union
{
unsigned char *buffer;
@@ -535,6 +536,16 @@ int open_socket (interface_t *iface, int protocol)
return (-1);
}
+ n = 1;
+ if (setsockopt (fd, SOL_PACKET, PACKET_AUXDATA, &n, sizeof(n)) < 0) {
+ if (errno != ENOPROTOOPT) {
+ logger (LOG_ERR, "failed to set auxiliary packet data: %s",
+ strerror (errno));
+ close (fd);
+ return (-1);
+ }
+ }
+
if (iface->fd > -1)
close (iface->fd);
iface->fd = fd;
@@ -594,13 +605,26 @@ ssize_t get_packet (const interface_t *iface, unsigned char *data,
unsigned char *buffer;
struct udp_dhcp_packet *packet;
} pay;
+ unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
+ struct iovec iov = {
+ .iov_base = buffer,
+ .iov_len = iface->buffer_length,
+ };
+ struct msghdr msg = {
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = cmsgbuf,
+ .msg_controllen = sizeof(cmsgbuf),
+ };
+ struct cmsghdr *cmsg;
+ int nocsum = 0;
/* We don't use the given buffer, but we need to rewind the position */
*buffer_pos = 0;
memset (buffer, 0, iface->buffer_length);
- bytes = read (iface->fd, buffer, iface->buffer_length);
+ bytes = recvmsg (iface->fd, &msg, 0);
if (bytes == -1) {
struct timespec ts;
logger (LOG_ERR, "read: %s", strerror (errno));
@@ -609,6 +633,13 @@ ssize_t get_packet (const interface_t *iface, unsigned char *data,
nanosleep (&ts, NULL);
return (-1);
}
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_PACKET &&
+ cmsg->cmsg_type == PACKET_AUXDATA) {
+ struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);
+ nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY;
+ }
+ }
*buffer_len = bytes;
/* If it's an ARP reply, then just send it back */
@@ -630,7 +661,7 @@ ssize_t get_packet (const interface_t *iface, unsigned char *data,
return (-1);
}
- if (valid_dhcp_packet (buffer) == -1)
+ if (valid_dhcp_packet (buffer, nocsum) == -1)
return (-1);
bytes = ntohs (pay.packet->ip.ip_len) -
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org