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
On Sun, 12 Apr 2015 10:14:36 +0200 Jose Miguel Sanchez Ales
<[email protected]> wrote:
Package: isc-dhcp-server
Version: 4.3.1-6
Severity: important
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-
-- System Information:
Debian Release: 8.0
APT prefers testing-updates
APT policy: (500, 'testing-updates'), (500, 'testing')
Architecture: amd64 (x86_64)
Kernel: Linux 3.16.0-4-amd64 (SMP w/1 CPU core)
Locale: LANG=es_ES.UTF-8, LC_CTYPE=es_ES.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages isc-dhcp-server depends on:
ii debconf [debconf-2.0] 1.5.56
ii debianutils 4.4+b1
ii isc-dhcp-common 4.3.1-6
ii libc6 2.19-17
ii libdns-export100 1:9.9.5.dfsg-9
ii libirs-export91 1:9.9.5.dfsg-9
ii libisc-export95 1:9.9.5.dfsg-9
ii lsb-base 4.1+Debian13+nmu1
isc-dhcp-server recommends no packages.