- Package:
- isc-dhcp-client
- Source:
- isc-dhcp
- Description:
- DHCP client for automatically obtaining an IP address
- Submitter:
- Ori Berger
- Date:
- 2026-08-05 17:34:05 UTC
- Severity:
- important
- Tags:
Dear isc-dhcp-client Maintainer,
There is a small omission in dhclient-script, which may cause a IP address to
be lost, with time to get an IP address again typically taking a 1-7 days (but
possibly a year or more), unless action is taken to reset it, e.g. by
ifdown/ifup on the interface.
* Evidence from syslog
sh[987]: DHCPDISCOVER on enp2s0 to 255.255.255.255 port 67 interval 9
(xid=0x93c8b31e)
dhclient[1001]: No DHCPOFFERS received.
sh[987]: No DHCPOFFERS received.
sh[987]: Trying recorded lease 172.50.55.101
dhclient[1001]: Trying recorded lease 172.50.55.101
sh[987]: PING 172.50.55.1 (172.50.55.1) 56(84) bytes of data.
sh[987]: --- 172.50.55.1 ping statistics ---
sh[987]: 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time
0ms
root: /etc/dhcp/dhclient-exit-hooks returned non-zero exit status 2
dhclient[1001]: bound: renewal in 477651 seconds.
sh[987]: bound: renewal in 477651 seconds.
* How it happens
basically, "if/then/else" in bash eats return codes: The following script is
instructive
----------
#!/bin/sh
return_1() {
return 1
}
return_1
echo "RC is $?"
if ! return_1; then
echo "then RC is $?"
else
echo "else RC is $?"
fi
----------
RC is 1
then RC is 0
----------
Let's assume a machine has an active lease for $interface (whether or not the
interface is already configured), and does not have a file called "/etc/dhcp
/dhcp-exit-hooks". Then, dhclient restarts (e.g., because of a reboot or an
apt-get upgrade) tries to renew the still valid lease, but times out because
the dhcp server is not responding for whatever reason. What we expect to happen
is a retry until an answer is received, with the interface maintaining its
address (if it has one) until the original lease expires, or continuing to re-
request the address until one is obtained. What actually happens is as follows:
1. dhclient (c side) calls dhclient-script with the TIMEOUT reason and all
parameters reflecting the existing lease.
2. dhclient-script TIMEOUT logic tries to ping the 1st router in the lease and
gets no reply
3. dhclient-script therefore flushes all IPs from interface using "ip -4 addr
flush dev ${interface}", and runs "exit_with_hooks 2"
4. exit_with_hooks initializes exit_status=2, and calls "run_hook /etc/dhcp
/dhclient-exit-hooks"
5. run_hook declares a local exit_status variable but does not initialize it,
so it retains the value 2 from the calling scope.
6. there is no /etc/dhcp/dhcp-exit-hooks script to run, so exit_status=2
remains.
7. run_hook wrongly logs an error in the (nonexistant) /etc/dhcp/dhclient-exit-
hooks using "logger -p"
9. run_hook still returns exit_status=2
10. back in exit_with_hooks, "run_hook" returned a non zero status 2. However,
the "if" test kills the $? return code, and as a result, the "then" part sets
exit_status=0
11. Let's assume that run_hookdir succeeds.
12. exit_with_hooks now exits with exit_status=0, indicating success
13. dhclient (c side) notes the success, assuming that the interface has been
set up (it is not, and even if it were - step 3 above flushes it) and sleeps
until the expiration of the original lease.
Result: we have an interface with no IP address, no attempt to renew it until
the original lease expires. Leases are typically 1-14 days, but some routers
give leases for a year.
* Temporary solution for an affected system (if you can issue commands to it,
e.g. through a console or another interface)
ifdown $interface && ifup $interface
Worked well for the system in which this was discovered.
* Potential Solution
1. In dhclient-script.linux, intiialize the local exit_status variable to 0,
as shown in the diff below.
----------
# run given script
run_hook() {
local script
- local exit_status
+ local exit_status=0
script="$1"
if [ -f $script ]; then
. $script
exit_status=$?
fi
if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then
logger -p daemon.err "$script returned non-zero exit status
$exit_status"
fi
return $exit_status
}
--------
2. In exit_with_hooks, replace both occurences of the construct
--------
if ! run_hook .... ; then
exit_status=$?
fi
--------
with something like
--------
$rc = run_hook ....
if [ $rc ne 0 ] then ; exit_status=$rc; fi
--------
* Note: Have not tried it yet in production. My bash/sh/dash is rusty, and I
wanted to report while I test my setting.
We believe that the bug you reported is fixed in the latest version of
isc-dhcp, which is due to be installed in the Debian FTP archive.
A summary of the changes between this version and the previous one is
attached.
Thank you for reporting the bug, which will now be closed. If you
have further comments please address them to 849100@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.
Debian distribution maintenance software
pp.
Michael Gilbert <mgilbert@debian.org> (supplier of updated isc-dhcp package)
(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Sun, 08 Jan 2017 23:11:52 +0000
Source: isc-dhcp
Binary: isc-dhcp-server isc-dhcp-server-ldap isc-dhcp-common isc-dhcp-dev isc-dhcp-client isc-dhcp-client-ddns isc-dhcp-client-udeb isc-dhcp-relay
Architecture: source
Version: 4.3.5-2
Distribution: unstable
Urgency: medium
Maintainer: Debian ISC DHCP maintainers <pkg-dhcp-devel@lists.alioth.debian.org>
Changed-By: Michael Gilbert <mgilbert@debian.org>
Description:
isc-dhcp-client - DHCP client for automatically obtaining an IP address
isc-dhcp-client-ddns - Dynamic DNS (DDNS) enabled DHCP client
isc-dhcp-client-udeb - ISC DHCP Client for debian-installer (udeb)
isc-dhcp-common - common manpages relevant to all of the isc-dhcp packages
isc-dhcp-dev - API for accessing and modifying the DHCP server and client state
isc-dhcp-relay - ISC DHCP relay daemon
isc-dhcp-server - ISC DHCP server for automatic IP address assignment
isc-dhcp-server-ldap - DHCP server that uses LDAP as its backend
Closes: 769189 816325 838382 841766 849100
Changes:
isc-dhcp (4.3.5-2) unstable; urgency=medium
.
* Fix new upstream spelling errors.
* Add policykit-1 dependency to the server package (closes: #816325).
* Parse IPv6 server process id from the correct file (closes: #841766).
* Initialize all local variables in dhclient scripts (closes: #849100).
* Pass random device to configure when cross building (closes: #838382).
- Thanks to Helmut Grohne.
* Don't wait for a reply that will never come when releasing an ipv6 address
(closes: #769189).
Checksums-Sha1:
b4ec987ac34f479f21ecbdb6a78006c8d6e41f29 3270 isc-dhcp_4.3.5-2.dsc
dfe6b15b319148c9a60b0078ad4f025b29705b2e 82744 isc-dhcp_4.3.5-2.debian.tar.xz
Checksums-Sha256:
100299d6bddb906367218ce65dd197c1eca4cff95046c66f3ad6c2d3d42a3c93 3270 isc-dhcp_4.3.5-2.dsc
a1c23e39c7ffff081b0492dbc434e0bd46655e4c9e4d2fdb04293a6a4745cf24 82744 isc-dhcp_4.3.5-2.debian.tar.xz
Files:
2a144882d03445f89c33ef8b10f37d58 3270 net important isc-dhcp_4.3.5-2.dsc
8cbfac05dde973fbe706c748d413ca97 82744 net important isc-dhcp_4.3.5-2.debian.tar.xz
-----BEGIN PGP SIGNATURE-----
iQQzBAEBCgAdFiEEluhy7ASCBulP9FUWuNayzQLW9HMFAlhzF0gACgkQuNayzQLW
9HOe5x//YSXsyUyFZcKL0eGJpyRhRBmbtoR2HDvvmwP69UJxO8tVrPVJQ0Goq9ea
fh5IphU1OOprrovaQEbv0LAQbjNIN0qNXc+YBBs9fXGjdH6Dg1za2d7oSArynBo1
mSI0vWmQAKPhU11a6TDUaiQZ5Y43pGMocgQ1yh0T/YOmiCv9qAE5xWP/zRQZGked
d5TwgPe8+D9UMafOQ68Z4VeeBOXEm0Rlvlc2pVFsoHtkcmFx5z2Lcmo0s6NlZCq/
Rv3Q5G5lo5+1WWJLyA+wO6dqgAgwhL58lSSALbIqX3SBPzECbb2M4q7IZUaH2SsR
0ajWwQsj1ygOV98lpGl3AxpWXxkosaIsj/fuLfXZc9AJrzLcvqkuKFSWN3O3aCyS
LkRyermf5qf7E+O8PBRVf1/vePhp4IWaSN2p04YhO4oqK3ch4EvTrrvzpNL9W8vn
9zjJG6IoouQcj7GV6th0aaMwS8HrLN3DmC+etiX1MxpoUzym3zBYh0Vrdq2SSuYH
A0lXP2edRs4nwA8X90TJxApByFa9qCoQLJ8uUGUCH60eTKZluTekhuZ/O9wfRz7h
8A3KtwWULDWjuokjg5zD59J9rrMXMzmQo2brdQn4IRBaDss8vi4ipX/1x/TH/Qf1
0nv/jF4f+ke0ujxnlRAK14NIvVUiE9qpNGb8ce+1QODPNCxf04n9pwkyAmyVgUZf
RafslI7a7eK4S6E0M2WtYiIBEQrpg3O+OVjXI1dwaxxd3o13wexJmwOjnOLbVXVh
vNhhk3VMb7FeERqb8bZhD7VAHqwwe2NlI+Ie8kU0+/AgPXJaORsC+9zO3+r5dVBe
W2BfQ/LhMgsr10mCgOf8WeIKdjL3FLJ1CMp1UBlK4US4rsoMtB9I0umv7PZyWy1B
vmxPiD1gfLyFhwengHg4eCKYPrZokVIRI0JNQFHdo/MiQVtK8BZ+F8lO/eE0yeky
1mhEsSJPmLtXAldoRZFFCJFNXxdBKGHXq3OF0s/O6gxCiyYDDfEzKYvtOrXaEM1K
WTKSDLISywY1MRn+tQQP4vqXsO8gzqk5O2TSJiVBWwj2TeGLVcC39oGUUzTS/c6K
/wdVkPtGCnYrfxcAzjwuqEjo7MCehoTqsjwwBrUIuogw2b4oB23U0td0YjUSJgL1
q2pu22o3L98AwN6Zgzis/ecTKXmiafXpedlFBQILL+hC7vpIbytUVTjl7z/vdkPe
YnRzpLN6la0hycpmXurJfNIRKHIyZ3J67cxgBTeCDVf1xRsMv2brPo9kL/wnlkBV
OefJM96d9Hnmw/IcjLa9BfsWEERfZU+w6xONEBsKbBnl5ZnXTaHwQhglY7aLHCIj
g1gBvih6Ihm4lRF4RgGoC0dMDZip9w==
=RZAv
-----END PGP SIGNATURE-----
Thank you for addressing my bug report #849100.
I believe, however, that the fix only partially addresses the bug.
In current master,
<https://anonscm.debian.org/cgit/pkg-dhcp/isc-dhcp.git/tree/debian/dhclient-script.linux#n144>
and
<https://anonscm.debian.org/cgit/pkg-dhcp/isc-dhcp.git/tree/debian/dhclient-script.linux#n149>,
(both in the same function "exit_with_hooks", there is a check of
success in the form
if ! run_something ; then
exit_status = $?
fi
Which is erronous - it is guaranteed to set exit_status=0 which is not
the intended result.
The reason this happens is that the "if/then" construct already eats the
$? return code. To get convince myself, I used the following test:
---script---
#!/bin/sh
return_1() {
return 1
}
return_1
echo "RC is $?"
if ! return_1; then
echo "then RC is $?"
else
echo "else RC is $?"
fi
---output---
RC is 1
then RC is 0
------------
The solution requires either:
if ! run_something ; then
exit_status = $?
fi
to be replaced with something like
run_something
exit_status=$((exit_status|$?))
or some other construct that stores the $? return code before "if/then"
eats it. I am not a shell expert, I'm not sure the fix above is exactly
what is needed, but as my example test script shows, there is still a bug.
Note that the man page for dhclient-script says: The exit status of dhclient-script will be passed to dhclient-exit-hooks in the exit_sta‐ tus shell variable, and will always be zero if the script succeeded at the task for which it was invoked. The rest of the environment as described previously for dhclient-enter- hooks is also present. The /etc/dhcp/dhclient-exit-hooks and /etc/dhcp/dhclient-exit- hooks.d/* scripts can modify the value of exit_status to change the exit status of dhclient-script. This seems to be in conflict with the implemented fix of setting exit_status=0 before calling the hooks. If the man page is correct, each script in turn should have the chance to update exit_status, and the value after calling the final script is the one to use for return. Arne
Dear submitter, as the package isc-dhcp has just been removed from the Debian archive unstable we hereby close the associated bug reports. We are sorry that we couldn't deal with your issue properly. For details on the removal, please see https://bugs.debian.org/1143544 The version of this package that was in Debian prior to this removal can still be found using https://snapshot.debian.org/. Please note that the changes have been done on the master archive and will not propagate to any mirrors until the next dinstall run at the earliest. This message was generated automatically; if you believe that there is a problem with it please contact the archive administrators by mailing ftpmaster@ftp-master.debian.org. Debian distribution maintenance software pp. Thorsten Alteholz (the ftpmaster behind the curtain)