summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2018-01-12 10:41:37 -0500
committerThomas Markwalder <tmark@isc.org>2018-01-12 10:41:37 -0500
commitdb4e4aa2e429a070f30c5795300a77312144bc8f (patch)
treee8ba1c2a2baa518a9573069b821a03a45fd13b29
parentd394b602d43f24cd96fff3fbfb0c7b386b352cca (diff)
downloadisc-dhcp-db4e4aa2e429a070f30c5795300a77312144bc8f.tar.gz
[master] Fixed relative file name crash
Merges in rt46957
-rw-r--r--RELNOTES7
-rw-r--r--client/dhclient.c10
-rw-r--r--common/print.c66
-rw-r--r--includes/dhcpd.h1
-rw-r--r--server/dhcpd.c6
5 files changed, 64 insertions, 26 deletions
diff --git a/RELNOTES b/RELNOTES
index 05d035bf..158b7e2f 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -103,6 +103,13 @@ by Eric Young (eay@cryptsoft.com).
cannot rely on the results of executable statements.
[ISC-Bugs #45451]
+- Fixed a bug which causes dhcpd and dhclient to crash on certain
+ systems when given relative path names for lease or pid files on
+ the command line. Affected systems are those on which the C library
+ function, realpath() does not support a second parameter value of
+ NULL (see manpages for realpath(3)).
+ [ISC-Bugs #46957]
+
Changes since 4.4.0a1 (New Features)
- Added experimental support for relay port (draft-ietf-dhc-relay-port-10.txt)
diff --git a/client/dhclient.c b/client/dhclient.c
index ac3cdbf8..825ab00f 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -639,17 +639,11 @@ main(int argc, char **argv) {
* to be reopened after chdir() has been called
*/
if (path_dhclient_db[0] != '/') {
- const char *old_path = path_dhclient_db;
- path_dhclient_db = realpath(path_dhclient_db, NULL);
- if (path_dhclient_db == NULL)
- log_fatal("Failed to get realpath for %s: %s", old_path, strerror(errno));
+ path_dhclient_db = absolute_path(path_dhclient_db);
}
if (path_dhclient_script[0] != '/') {
- const char *old_path = path_dhclient_script;
- path_dhclient_script = realpath(path_dhclient_script, NULL);
- if (path_dhclient_script == NULL)
- log_fatal("Failed to get realpath for %s: %s", old_path, strerror(errno));
+ path_dhclient_script = absolute_path(path_dhclient_script);
}
/*
diff --git a/common/print.c b/common/print.c
index 5993c0e2..8727b4fa 100644
--- a/common/print.c
+++ b/common/print.c
@@ -3,7 +3,7 @@
Turn data structures into printable text. */
/*
- * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2018 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* This Source Code Form is subject to the terms of the Mozilla Public
@@ -132,7 +132,7 @@ char *print_base64 (const unsigned char *buf, unsigned len,
b = dmalloc (bl + 1, file, line);
if (!b)
return (char *)0;
-
+
i = 0;
s = b;
while (i != len) {
@@ -199,15 +199,15 @@ void print_lease (lease)
log_debug (" Lease %s",
piaddr (lease -> ip_addr));
-
+
t = gmtime (&lease -> starts);
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
log_debug (" start %s", tbuf);
-
+
t = gmtime (&lease -> ends);
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
log_debug (" end %s", tbuf);
-
+
if (lease -> hardware_addr.hlen)
log_debug (" hardware addr = %s",
print_hw_addr (lease -> hardware_addr.hbuf [0],
@@ -215,7 +215,7 @@ void print_lease (lease)
&lease -> hardware_addr.hbuf [1]));
log_debug (" host %s ",
lease -> host ? lease -> host -> name : "<none>");
-}
+}
#if defined (DEBUG_PACKET)
void dump_packet_option (struct option_cache *oc,
@@ -301,7 +301,7 @@ void dump_raw (buf, len)
/*
1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123
-280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
+280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
*/
memset(lbuf, ' ', 79);
@@ -446,7 +446,7 @@ void print_hex_or_string (len, data, limit, buf)
/*
* print a string as either hex or text
* using static buffers to hold the output
- *
+ *
* len - length of data
* data - input data
* limit - length of buf
@@ -499,7 +499,7 @@ char *print_dotted_quads (len, data)
char *s;
s = &dq_buf [0];
-
+
i = 0;
/* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe%
@@ -554,7 +554,7 @@ static unsigned print_subexpression (expr, buf, len)
return 3;
}
break;
-
+
case expr_match:
if (len > 7) {
strcpy (buf, "(match)");
@@ -772,7 +772,7 @@ static unsigned print_subexpression (expr, buf, len)
case expr_binary_xor:
s = "^";
goto binop;
-
+
case expr_not:
if (len > 6) {
rv = 5;
@@ -1179,7 +1179,7 @@ void print_expression (name, expr)
}
int token_print_indent_concat (FILE *file, int col, int indent,
- const char *prefix,
+ const char *prefix,
const char *suffix, ...)
{
va_list list;
@@ -1209,7 +1209,7 @@ int token_print_indent_concat (FILE *file, int col, int indent,
s = va_arg (list, char *);
}
va_end (list);
-
+
col = token_print_indent (file, col, indent,
prefix, suffix, t);
dfree (t, MDL);
@@ -1439,3 +1439,43 @@ char *format_lease_id(const unsigned char *s, unsigned len,
}
return (idstr);
}
+
+/*
+ * Convert a relative path name to an absolute path name
+ *
+ * Not all versions of realpath() support NULL for
+ * the second parameter and PATH_MAX isn't defined
+ * on all systems. For the latter, we'll make what
+ * ought to be a big enough buffer and let it fly.
+ * If passed an absolute path it should return it
+ * an allocated buffer.
+ */
+char *absolute_path(const char *orgpath) {
+ char *abspath = NULL;
+ if (orgpath) {
+#ifdef PATH_MAX
+ char buf[PATH_MAX];
+#else
+ char buf[2048];
+ int len;
+#endif
+ errno = 0;
+ if (realpath(orgpath, buf) == NULL) {
+ const char* errmsg = strerror(errno);
+ log_fatal("Failed to get realpath for %s: %s",
+ orgpath, errmsg);
+ }
+
+ /* dup the result into an allocated buffer */
+ abspath = dmalloc(strlen(buf) + 1, MDL);
+ if (abspath == NULL) {
+ log_fatal("No memory for filename:%s\n",
+ buf);
+ }
+
+ memcpy (abspath, buf, strlen(buf));
+ abspath[strlen(buf)] = 0x0;
+ }
+
+ return (abspath);
+}
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 90456b76..24c8146f 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2635,6 +2635,7 @@ char *buf_to_hex (const unsigned char *s, unsigned len,
const char *file, int line);
char *format_lease_id(const unsigned char *s, unsigned len, int format,
const char *file, int line);
+char *absolute_path(const char *orgpath);
/* socket.c */
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
|| defined (USE_SOCKET_FALLBACK)
diff --git a/server/dhcpd.c b/server/dhcpd.c
index 4ac8bd75..55ffae70 100644
--- a/server/dhcpd.c
+++ b/server/dhcpd.c
@@ -607,11 +607,7 @@ main(int argc, char **argv) {
* to be reopened after chdir() has been called
*/
if (have_dhcpd_db && path_dhcpd_db[0] != '/') {
- const char *path = path_dhcpd_db;
- path_dhcpd_db = realpath(path_dhcpd_db, NULL);
- if (path_dhcpd_db == NULL)
- log_fatal("Failed to get realpath for %s: %s", path,
- strerror(errno));
+ path_dhcpd_db = absolute_path(path_dhcpd_db);
}
if (!quiet) {