[pkg-dhcp-devel] Bug#616290: ISC-Bugs #25979: FTBFS of isc-dhcp for GNU/Hurd

Samuel Thibault samuel.thibault at gnu.org
Fri Jan 13 02:11:06 UTC 2012


Hello,

(dropping Cc debian-devel, it's not worth it)

Here is an updated version of the patch, as well as some information
about it, I've both attached the patch and commented it below. There is
also an additional patch for the embedded bind code. Eventually, there
is an empty rfc3442 script for now.

> --- isc-dhcp-4.1.1-P1~/client/dhclient.c	2011-03-03 01:10:28.000000000 +0000
> +++ isc-dhcp-4.1.1-P1/client/dhclient.c	2011-03-03 01:11:08.000000000 +0000
> @@ -342,21 +342,33 @@
>  	 * to be reopened after chdir() has been called
>  	 */
>  	if (path_dhclient_db[0] != '/') {
> -		char *path = dmalloc(PATH_MAX, MDL);

PATH_MAX is not defined on GNU/Hurd, because there is no such hard
path length limitation. But since it's a GNU system, there's the nice
extension (which is now also in POSIX 2008 actually) saying that
realpath allocates the required memory when its argument is NULL, so the
following hook simply replaces on GNU the PATH_MAX allocation with a
mere call to realpath:

> +		char *path;
> +#ifdef __GLIBC__
> +		path = realpath(path_dhclient_db, NULL);
> +#else
> +		path = dmalloc(PATH_MAX, MDL);
>  		if (path == NULL)
>  			log_fatal("No memory for filename\n");
> -		path_dhclient_db = realpath(path_dhclient_db, path);
> -		if (path_dhclient_db == NULL)
> -			log_fatal("%s: %s", path, strerror(errno));
> +		path = realpath(path_dhclient_db, path);
> +#endif

The failure code if factorized. Note that there was actually a bug in
the original code: if realpath returns NULL, the string pointed by
path was undefined. Storing the result of realpath in path instead of
path_dhclient_db allows to print the culprit path:

> +		if (path == NULL)
> +			log_fatal("%s: %s", path_dhclient_db, strerror(errno));
> +		path_dhclient_db = path;

In both cases path_dhclient_db ends up pointing on a newly-allocated
string, so there is no allocation issue.

>  	}
 

Ditto.

>  	if (path_dhclient_script[0] != '/') {
> -		char *path = dmalloc(PATH_MAX, MDL);
> +		char *path;
> +#ifdef __GLIBC__
> +		path = realpath(path_dhclient_script, NULL);
> +#else
> +		path = dmalloc(PATH_MAX, MDL);
>  		if (path == NULL)
>  			log_fatal("No memory for filename\n");
> -		path_dhclient_script = realpath(path_dhclient_script, path);
> -		if (path_dhclient_script == NULL)
> -			log_fatal("%s: %s", path, strerror(errno));
> +		path = realpath(path_dhclient_script, path);
> +#endif
> +		if (path == NULL)
> +			log_fatal("%s: %s", path_dhclient_script, strerror(errno));
> +		path_dhclient_script = path;
>  	}
>  
>  	/* first kill off any currently running client */


Ditto

> diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/server/dhcpd.c isc-dhcp-4.1.1-P1/server/dhcpd.c
> --- isc-dhcp-4.1.1-P1~/server/dhcpd.c	2011-03-03 01:06:44.000000000 +0000
> +++ isc-dhcp-4.1.1-P1/server/dhcpd.c	2011-03-03 01:11:08.000000000 +0000
> @@ -449,12 +449,18 @@
>           * to be reopened after chdir() has been called
>           */
>          if (path_dhcpd_db[0] != '/') {
> -                char *path = dmalloc(PATH_MAX, MDL);
> +                char *path;
> +#ifdef __GLIBC__
> +                path = realpath(path_dhcpd_db, NULL);
> +#else
> +                path = dmalloc(PATH_MAX, MDL);
>                  if (path == NULL)
>                          log_fatal("No memory for filename\n");
> -                path_dhcpd_db = realpath(path_dhcpd_db,  path);
> -                if (path_dhcpd_db == NULL)
> -                        log_fatal("%s: %s", path, strerror(errno));
> +                path = realpath(path_dhcpd_db, path);
> +#endif
> +                if (path == NULL)
> +                        log_fatal("%s: %s", path_dhcpd_db, strerror(errno));
> +                path_dhcpd_db = path;
>          }
>  
>  	if (!quiet) {

The following changes add support for being fine with just using only
the standard BSD socket API (GNU/Hurd has neither linux/filter.h, nor
sys/dlpi.h, nor net/bpf.h, but that's not actually mandatory for basic
dhcp support). Otherwise, undefined references to send_packet etc. would
be emitted.

> diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/configure.ac isc-dhcp-4.1.1-P1/configure.ac
> --- isc-dhcp-4.1.1-P1~/configure.ac	2011-03-03 01:10:44.000000000 +0000
> +++ isc-dhcp-4.1.1-P1/configure.ac	2011-03-03 01:11:36.000000000 +0000
> @@ -366,9 +366,17 @@
>  		AC_CHECK_HEADER(net/bpf.h, DO_BPF=1)
>  		if test -n "$DO_BPF"
>  		then
> -			AC_DEFINE([HAVE_BPF], [""],
> +			AC_DEFINE([HAVE_BPF], [1],
>  	  			  [Define to 1 to use the 
>  				   Berkeley Packet Filter interface code.])
> +		else

Testing the presence of the BSD interface as automatic last resort
(without having to specify --enable-use-sockets).

> +			AC_CHECK_HEADER(sys/socket.h, DO_SOCKET=1)
> +			if test -n "$DO_SOCKET"
> +			then
> +				AC_DEFINE([HAVE_SOCKETS], [1],
> +				[Define to 1 to use the
> +				 standard BSD socket API.])
> +			fi
>  		fi
>  	fi
>  fi

An autoconf run is of course needed to propagage these changes to
configure.


> diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/includes/osdep.h isc-dhcp-4.1.1-P1/includes/osdep.h
> --- isc-dhcp-4.1.1-P1~/includes/osdep.h	2011-03-03 01:06:44.000000000 +0000
> +++ isc-dhcp-4.1.1-P1/includes/osdep.h	2011-03-03 01:13:23.000000000 +0000
> @@ -116,6 +118,8 @@
>  #  define USE_SOCKET_RECEIVE
>  #  if defined(HAVE_DLPI)
>  #    define USE_DLPI_HWADDR

We here (in the USE_SOCKETS case) introduce USE_LPF_HWADDR, which means
using just ioctl(SIOCGIFHWADDR) on the socket to get the hardware
address. Otherwise we get an undefined get_hw_addr reference.

> +#  else
> +#    define USE_LPF_HWADDR
>  #  endif
>  #endif

Now the lpf.c patch permits to define get_hw_addr().

> diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/common/lpf.c isc-dhcp-4.1.1-P1/common/lpf.c
> --- isc-dhcp-4.1.1-P1~/common/lpf.c	2011-03-03 01:06:44.000000000 +0000
> +++ isc-dhcp-4.1.1-P1/common/lpf.c	2011-03-03 01:11:08.000000000 +0000
> @@ -28,7 +28,6 @@
>  
>  #include "dhcpd.h"
>  #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)

sys/ioctl is only used for lpf_receive:

> -#include <sys/ioctl.h>
>  #include <sys/uio.h>
>  #include <errno.h>
>  
> @@ -39,8 +38,14 @@
>  #include "includes/netinet/ip.h"
>  #include "includes/netinet/udp.h"
>  #include "includes/netinet/if_ether.h"
> +#endif

moved here:

> +#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
> +#include <sys/ioctl.h>

net/if.h is also only used for lpf_receive:

>  #include <net/if.h>
> +#endif

Get back to the original inclusion condition for most of the code:

> +#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
>  /* Reinitializes the specified interface after an address change.   This
>     is not required for packet-filter APIs. */
>  
> @@ -411,7 +416,9 @@
>  		interface_dereference (&fbi, MDL);
>  	}
>  }
> +#endif

get_hw_addr is actually only needed for lpf_receive, and will now be
used for lpf_hwaddr too:

> +#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
>  void
>  get_hw_addr(const char *name, struct hardware *hw) {
>  	int sock;




Last but not least, GNU/Hurd uses the same headers as Linux, so it needs
the same knobs in bind (already reported as #651001).

This is needed because otherwise bind believes there is no in6_pktinfo
structure, and defines it in its headers, which when included in the
isc-dhcp code (which does define _GNU_SOURCE) then conflicts with the
system-provided definition.

> --- bind/bind-9.8.0-P4/configure.in.orig	2012-01-13 01:59:50.000000000 +0100
> +++ bind/bind-9.8.0-P4/configure.in	2012-01-13 02:00:00.000000000 +0100
> @@ -263,7 +263,7 @@
>  	# as it breaks how the two halves (Basic and Advanced) of the IPv6
>  	# Socket API were designed to be used but we have to live with it.
>  	# Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API.
> -	*-linux*)
> +	*-linux*|*-gnu*)
>  		STD_CDEFINES="$STD_CDEFINES -D_GNU_SOURCE"
>  		CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
>  		;;
> --- bind/bind-9.8.0-P4/configure.orig	2012-01-13 02:00:47.000000000 +0100
> +++ bind/bind-9.8.0-P4/configure	2012-01-13 02:02:44.000000000 +0100
> @@ -19613,7 +19613,7 @@
>  	# as it breaks how the two halves (Basic and Advanced) of the IPv6
>  	# Socket API were designed to be used but we have to live with it.
>  	# Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API.
> -	*-linux*)
> +	*-linux*|*-gnu*)
>  		STD_CDEFINES="$STD_CDEFINES -D_GNU_SOURCE"
>  		CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
>  		;;
-------------- next part --------------
#! /bin/sh /usr/share/dpatch/dpatch-run
# fix FTPFS for GNU/Hurd
@DPATCH@
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/client/dhclient.c isc-dhcp-4.1.1-P1/client/dhclient.c
--- isc-dhcp-4.1.1-P1~/client/dhclient.c	2011-03-03 01:10:28.000000000 +0000
+++ isc-dhcp-4.1.1-P1/client/dhclient.c	2011-03-03 01:11:08.000000000 +0000
@@ -342,21 +342,33 @@
 	 * to be reopened after chdir() has been called
 	 */
 	if (path_dhclient_db[0] != '/') {
-		char *path = dmalloc(PATH_MAX, MDL);
+		char *path;
+#ifdef __GLIBC__
+		path = realpath(path_dhclient_db, NULL);
+#else
+		path = dmalloc(PATH_MAX, MDL);
 		if (path == NULL)
 			log_fatal("No memory for filename\n");
-		path_dhclient_db = realpath(path_dhclient_db, path);
-		if (path_dhclient_db == NULL)
-			log_fatal("%s: %s", path, strerror(errno));
+		path = realpath(path_dhclient_db, path);
+#endif
+		if (path == NULL)
+			log_fatal("%s: %s", path_dhclient_db, strerror(errno));
+		path_dhclient_db = path;
 	}
 
 	if (path_dhclient_script[0] != '/') {
-		char *path = dmalloc(PATH_MAX, MDL);
+		char *path;
+#ifdef __GLIBC__
+		path = realpath(path_dhclient_script, NULL);
+#else
+		path = dmalloc(PATH_MAX, MDL);
 		if (path == NULL)
 			log_fatal("No memory for filename\n");
-		path_dhclient_script = realpath(path_dhclient_script, path);
-		if (path_dhclient_script == NULL)
-			log_fatal("%s: %s", path, strerror(errno));
+		path = realpath(path_dhclient_script, path);
+#endif
+		if (path == NULL)
+			log_fatal("%s: %s", path_dhclient_script, strerror(errno));
+		path_dhclient_script = path;
 	}
 
 	/* first kill off any currently running client */
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/server/dhcpd.c isc-dhcp-4.1.1-P1/server/dhcpd.c
--- isc-dhcp-4.1.1-P1~/server/dhcpd.c	2011-03-03 01:06:44.000000000 +0000
+++ isc-dhcp-4.1.1-P1/server/dhcpd.c	2011-03-03 01:11:08.000000000 +0000
@@ -449,12 +449,18 @@
          * to be reopened after chdir() has been called
          */
         if (path_dhcpd_db[0] != '/') {
-                char *path = dmalloc(PATH_MAX, MDL);
+                char *path;
+#ifdef __GLIBC__
+                path = realpath(path_dhcpd_db, NULL);
+#else
+                path = dmalloc(PATH_MAX, MDL);
                 if (path == NULL)
                         log_fatal("No memory for filename\n");
-                path_dhcpd_db = realpath(path_dhcpd_db,  path);
-                if (path_dhcpd_db == NULL)
-                        log_fatal("%s: %s", path, strerror(errno));
+                path = realpath(path_dhcpd_db, path);
+#endif
+                if (path == NULL)
+                        log_fatal("%s: %s", path_dhcpd_db, strerror(errno));
+                path_dhcpd_db = path;
         }
 
 	if (!quiet) {
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/configure.ac isc-dhcp-4.1.1-P1/configure.ac
--- isc-dhcp-4.1.1-P1~/configure.ac	2011-03-03 01:10:44.000000000 +0000
+++ isc-dhcp-4.1.1-P1/configure.ac	2011-03-03 01:11:36.000000000 +0000
@@ -366,9 +366,17 @@
 		AC_CHECK_HEADER(net/bpf.h, DO_BPF=1)
 		if test -n "$DO_BPF"
 		then
-			AC_DEFINE([HAVE_BPF], [""],
+			AC_DEFINE([HAVE_BPF], [1],
 	  			  [Define to 1 to use the 
 				   Berkeley Packet Filter interface code.])
+		else
+			AC_CHECK_HEADER(sys/socket.h, DO_SOCKET=1)
+			if test -n "$DO_SOCKET"
+			then
+				AC_DEFINE([USE_SOCKETS], [1],
+				[Define to 1 to use the
+				 standard BSD socket API.])
+			fi
 		fi
 	fi
 fi
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/includes/osdep.h isc-dhcp-4.1.1-P1/includes/osdep.h
--- isc-dhcp-4.1.1-P1~/includes/osdep.h	2011-03-03 01:06:44.000000000 +0000
+++ isc-dhcp-4.1.1-P1/includes/osdep.h	2011-03-03 01:13:23.000000000 +0000
@@ -116,6 +116,8 @@
 #  define USE_SOCKET_RECEIVE
 #  if defined(HAVE_DLPI)
 #    define USE_DLPI_HWADDR
+#  else
+#    define USE_LPF_HWADDR
 #  endif
 #endif
 
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.1-P1~/common/lpf.c isc-dhcp-4.1.1-P1/common/lpf.c
--- isc-dhcp-4.1.1-P1~/common/lpf.c	2011-03-03 01:06:44.000000000 +0000
+++ isc-dhcp-4.1.1-P1/common/lpf.c	2011-03-03 01:11:08.000000000 +0000
@@ -28,7 +28,6 @@
 
 #include "dhcpd.h"
 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
-#include <sys/ioctl.h>
 #include <sys/uio.h>
 #include <errno.h>
 
@@ -39,8 +38,14 @@
 #include "includes/netinet/ip.h"
 #include "includes/netinet/udp.h"
 #include "includes/netinet/if_ether.h"
+#endif
+
+#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
+#include <sys/ioctl.h>
 #include <net/if.h>
+#endif
 
+#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
 /* Reinitializes the specified interface after an address change.   This
    is not required for packet-filter APIs. */
 
@@ -411,7 +416,9 @@
 		interface_dereference (&fbi, MDL);
 	}
 }
+#endif
 
+#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
 void
 get_hw_addr(const char *name, struct hardware *hw) {
 	int sock;
-------------- next part --------------
--- bind/bind-9.8.0-P4/configure.in.orig	2012-01-13 01:59:50.000000000 +0100
+++ bind/bind-9.8.0-P4/configure.in	2012-01-13 02:00:00.000000000 +0100
@@ -263,7 +263,7 @@
 	# as it breaks how the two halves (Basic and Advanced) of the IPv6
 	# Socket API were designed to be used but we have to live with it.
 	# Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API.
-	*-linux*)
+	*-linux*|*-gnu*)
 		STD_CDEFINES="$STD_CDEFINES -D_GNU_SOURCE"
 		CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
 		;;
--- bind/bind-9.8.0-P4/configure.orig	2012-01-13 02:00:47.000000000 +0100
+++ bind/bind-9.8.0-P4/configure	2012-01-13 02:02:44.000000000 +0100
@@ -19613,7 +19613,7 @@
 	# as it breaks how the two halves (Basic and Advanced) of the IPv6
 	# Socket API were designed to be used but we have to live with it.
 	# Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API.
-	*-linux*)
+	*-linux*|*-gnu*)
 		STD_CDEFINES="$STD_CDEFINES -D_GNU_SOURCE"
 		CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
 		;;
-------------- next part --------------
:


More information about the pkg-dhcp-devel mailing list