#782434 isc-dhcp-server: DHCP server segfaults when exceeding lease limit

Package:
isc-dhcp-server
Source:
isc-dhcp
Description:
ISC DHCP server for automatic IP address assignment
Submitter:
Jose Miguel Sanchez Ales
Date:
2026-08-05 17:33:57 UTC
Severity:
important
Tags:
#782434#5
Date:
2015-04-12 08:14:36 UTC
From:
To:
Dear Maintainer,

The dhcpd server dies with segmentation fault when exceeds the lease
limit in a class. For example:

#v+
class "foo" {
   match if 1 = 1;
   lease limit 1;
}
#v-

At first time, a client obtains ip and exhausts the limit:

#v+
Apr 12 09:32:06 zipi dhcpd: DHCPREQUEST for 192.168.255.106 from 00:11:22:33:44:55 via eth1
Apr 12 09:32:06 zipi dhcpd: DHCPACK on 192.168.255.106 to 00:11:22:33:44:55 (qos2) via eth1
#v-

However if a second client makes a request, the DHCP server dies:

#v+
Apr 12 09:32:33 zipi dhcpd: DHCPREQUEST for 192.168.255.106 from 00:11:22:33:44:56 via eth1: lease 192.168.255.106 unavailable.
Apr 12 09:32:33 zipi dhcpd: DHCPNAK on 192.168.255.106 to 00:11:22:33:44:56 via eth1
Apr 12 09:32:33 zipi kernel: [  607.009131] dhcpd[9787]: segfault at 30 ip 00007f31ee2d3333 sp 00007ffc6a94f300 error 4 in dhcpd[7f31ee2bc000+b3000]
#v-

On wheezy the behavior is correct:

#v+
DHCPDISCOVER from 00:11:22:33:44:70 via eth1: no available billing: lease limit reached in all matching classes
#v-

#782434#10
Date:
2017-01-14 21:32:23 UTC
From:
To:
control: tag -1 moreinfo

A similar problem with lease limits on 64-bit systems was fixed in the
client in 4.3.3-2, bug #795227.  Did that also fix this?

Best wishes,
Mike

#782434#17
Date:
2019-04-09 17:00:47 UTC
From:
To:
Dear Maintainer,

the bug is still exists in 4.4.1 when lease limits are used as described
before.

gdb:
Breakpoint 1, ack_lease (packet=packet@entry=0x555556c24780,
lease=0x555556224630, offer=offer@entry=2, when=1554726300,
msg=msg@entry=0x7fffffffcc90 "DHCPDISCOVER from 90:6e:bb:4d:77:e7 via
10.96.160.1",
     ms_nulltp=ms_nulltp@entry=0, hp=0x0) at dhcp.c:2570
2570	in dhcp.c

Somewhere in 4.3.x this function is changed to:
                 /* If we don't have an active billing, see if we need
                    one, and if we do, try to do so. */
                 if (lease->billing_class == NULL) {
                         char *cname = "";
                         int bill = 0;

                         for (i = 0; i < packet->class_count; i++) {
                                 struct class *billclass, *subclass;

                                 billclass = packet->classes[i];
                                 if (billclass->lease_limit) {
                                         bill++;
                                         if (bill_class(lease, billclass))
                                                 break;

                                         subclass = billclass->superclass;
                                         if (subclass == NULL)
                                                 cname = subclass->name;
                                         else
                                                 cname = billclass->name;
                                 }
                         }

where gdb points:

                                                 cname = subclass->name;

As you see, the if statement is TRUE, when sublass is NULL, then it
tries to use NULL value on subclaass->name.

The old working code was:
                 if (lease->billing_class == NULL) {
                         int bill = 0;
                         for (i = 0; i < packet->class_count; i++) {
                                 if (packet->classes[i]->lease_limit) {
                                         bill++;
                                         if (bill_class(lease,
                                                        packet->classes[i]))
                                                 break;
                                 }
                         }

I've patched 4.4.1 with the old one.

Patch:
--- isc-dhcp-4.4.1.orig/server/dhcp.c
+++ isc-dhcp-4.4.1/server/dhcp.c
@@ -2554,24 +2554,16 @@ void ack_lease (packet, lease, offer, wh
                    one, and if we do, try to do so. */
                 if (lease->billing_class == NULL) {
                         char *cname = "";
-                       int bill = 0;
+                        int bill = 0;
+                        for (i = 0; i < packet->class_count; i++) {
+                                if (packet->classes[i]->lease_limit) {
+                                        bill++;
+                                        if (bill_class(lease,
+                                                       packet->classes[i]))
+                                                break;
+                                }
+                        }

-                       for (i = 0; i < packet->class_count; i++) {
-                               struct class *billclass, *subclass;
-
-                               billclass = packet->classes[i];
-                               if (billclass->lease_limit) {
-                                       bill++;
-                                       if (bill_class(lease, billclass))
-                                               break;
-
-                                       subclass = billclass->superclass;
-                                       if (subclass == NULL)


I've started to test it on production environments (IPv4, IPv6). I'll
report what happens after a few days.

Peter Nagy

#782434#22
Date:
2019-07-31 16:01:51 UTC
From:
To:
Hi , thanks for your message. We'll get back to you soon!"
#782434#27
Date:
2026-08-05 17:31:09 UTC
From:
To:
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)