Bug report: dhcp+LDAP with dynamic configuration leaks memory; DoS potential

Alex Bligh alex at alex.org.uk
Wed May 4 17:45:42 UTC 2011



--On 4 May 2011 17:38:47 +0100 Alex Bligh <alex at alex.org.uk> wrote:

> Extensive investigation shows dhcp+ldap is leaking memory. Sending 494
> discover packets for which there is an LDAP record leaks around 90k
> of memory, so this is reasonably serious.

I think I should have been a bit more thorough in the bug report. It's
a "fixed-address" that I see triggering it.

Example files below. Invoking tester.pl from a connected machine with
 ./tester.pl -m -n 021111111112
and appropriate other parameters causes the leak.

Getting openldap set up is non-trivial; I have scripts to install it
on Ubuntu Lucid, and set up all the DBs to include the ldap schema
if that is interesting.

Alternatively, you can apply my DBI/SQL patch which demonstrates
the bug in the same way (which is probably easier).

-- 
Alex Bligh


# cat /etc/dhcp/dhcpd.ldif

dn: cn=alextest, dc=example,dc=com
cn: alextest
objectClass: top
objectClass: dhcpServer
dhcpServiceDN: cn=DHCP Config, dc=example,dc=com

dn: cn=DHCP Config, dc=example,dc=com
cn: DHCP Config
objectClass: top
objectClass: dhcpService
dhcpPrimaryDN: cn=alextest, dc=example,dc=com
dhcpStatements: ddns-update-style none
dhcpStatements: ignore client-updates
dhcpStatements: authoritative

dn: cn=0.0.0.0, cn=DHCP Config, dc=example,dc=com
cn: 0.0.0.0
objectClass: top
objectClass: dhcpSubnet
dhcpNetMask: 0

dn: cn=test, cn=0.0.0.0, cn=DHCP Config, dc=example,dc=com
cn: test
objectClass: top
objectClass: dhcpHost
dhcpHWAddress: ethernet 02:11:11:11:11:12
dhcpStatements: fixed-address 99.99.99.99

# cat /etc/dhcp/dhcpd.conf

ldap-server "127.0.0.1";
ldap-port 389;
ldap-base-dn  "dc=example,dc=com";
ldap-debug-file "/var/log/dhcp-ldap-startup.log";
ldap-dhcp-server-cn "alextest";
ldap-password "xxx";
ldap-method dynamic;
ddns-update-style none;

$ cat tester.pl
#!/usr/bin/perl
use Sys::Hostname;
use Socket;
use Net::DHCP::Session;
use Getopt::Long;
use strict;



#################################################################################
# usage() 
#
# 
#
#################################################################################
sub usage {
	"Usage: dhc.pl -d <IP DHCP server> [-l <local IP addr>] [-m <mac>] [-h 
hostname] [-i]\n" .
	" -d <IP DHCP server> = IP address of DHCP server to use.\n".
	" -l <local IP addr> = If your local host has several addresses, \n" .
	"		specify the address to use. Optional.\n".
	" -m <mac> = Client MAC address for DHCP requests. Format : ex. 
00065B011AAA.\n" .
	" -h <host> = hostname (DHCP Option 12)" .
	" -n = Don't wait for offer\n";
	" -i = interactive mode\n";
}

my $DHCPserver = undef;
my $localaddr = undef;
my $interactive = undef;
my $nowait = undef;
my $mac = undef;
my $hostname = 'dhcFake';

GetOptions (
'dhcpserver=s' => \$DHCPserver,
'localaddr=s' => \$localaddr,
'mac=s' => \$mac,
'hostname=s' => \$hostname,
'nowait' => \$nowait,
'interactive' => \$interactive
) || die usage();

$DHCPserver || die usage();
$mac = Net::DHCP::Session::genMAC() unless defined ($mac);
$localaddr = inet_ntoa ( scalar ( gethostbyname(hostname()) ) ) unless 
defined ($localaddr);

print "using mac $mac...\n";
print "using localaddr $localaddr...\n";

my $dhc = new Net::DHCP::Session(Hostname => $hostname,
		Localaddr => $localaddr,
		Server_ip => $DHCPserver,
		Chaddr => $mac);
$dhc->discover();
exit (0) if (defined ($nowait));
$dhc->await_offer();
$dhc->request();
$dhc->await_ack();

print $dhc->dumpoptions();





More information about the dhcp-users mailing list