--- dhcp-4.3.4/client/dhclient.c.orig 2016-09-28 12:29:47.517939066 +0300 +++ dhcp-4.3.4/client/dhclient.c 2016-09-28 12:34:37.535000111 +0300 @@ -33,17 +33,24 @@ #include "dhcpd.h" #include #include +#include +#include #include +#include +#include +#include #include #include #include #include #include +#include #ifdef HAVE_LIBCAP_NG #include #endif + /* * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define * that when building ISC code. @@ -207,7 +214,6 @@ main(int argc, char **argv) { int i; struct interface_info *ip; struct client_state *client; - unsigned seed; char *server = NULL; isc_result_t status; int exit_mode = 0; @@ -1045,26 +1051,6 @@ main(int argc, char **argv) { } } - /* We create a backup seed before rediscovering interfaces in order to - have a seed built using all of the available interfaces - It's interesting if required interfaces doesn't let us defined - a really unique seed due to a lack of valid HW addr later - (this is the case with DHCP over IB) - We only use the last device as using a sum could broke the - uniqueness of the seed among multiple nodes - */ - unsigned backup_seed = 0; - for (ip = interfaces; ip; ip = ip -> next) { - int junk; - if ( ip -> hw_address.hlen <= sizeof seed ) - continue; - memcpy (&junk, - &ip -> hw_address.hbuf [ip -> hw_address.hlen - - sizeof seed], sizeof seed); - backup_seed = junk; - } - - /* At this point, all the interfaces that the script thinks are relevant should be running, so now we once again call discover_interfaces(), and this time ask it to actually set @@ -1073,43 +1059,6 @@ main(int argc, char **argv) { ? DISCOVER_REQUESTED : DISCOVER_RUNNING); - /* Make up a seed for the random number generator from current - time plus the sum of the last four bytes of each - interface's hardware address interpreted as an integer. - Not much entropy, but we're booting, so we're not likely to - find anything better. */ - seed = 0; - int seed_flag = 0; - for (ip = interfaces; ip; ip = ip->next) { - int junk; - if ( ip -> hw_address.hlen <= sizeof seed ) - continue; - memcpy(&junk, - &ip->hw_address.hbuf[ip->hw_address.hlen - - sizeof seed], sizeof seed); - seed += junk; - seed_flag = 1; - } - if ( seed_flag == 0 ) { - if ( backup_seed != 0 ) { - seed = backup_seed; - log_info ("xid: rand init seed (0x%x) built using all" - " available interfaces",seed); - } - else { - seed = cur_time^((unsigned) gethostid()) ; - log_info ("xid: warning: no netdev with useable HWADDR found" - " for seed's uniqueness enforcement"); - log_info ("xid: rand init seed (0x%x) built using gethostid", - seed); - } - /* we only use seed and no current time as a broadcast reply */ - /* will certainly be used by the hwaddrless interface */ - srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid()); - } - else - srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid()); - /* Setup specific Infiniband options */ for (ip = interfaces; ip; ip = ip->next) { if (ip->client && @@ -1138,6 +1087,8 @@ main(int argc, char **argv) { dhcp4o6_setup(dhcp4o6_port); #endif + (void)charcrandom_u32(); + /* Start a configuration state machine for each interface. */ #ifdef DHCPv6 if (local_family == AF_INET6) { @@ -1182,10 +1133,10 @@ main(int argc, char **argv) { if (top_level_config. initial_delay>1) tv.tv_sec = cur_time - + random() + + charcrandom_u32() % (top_level_config. initial_delay-1); - tv.tv_usec = random() + tv.tv_usec = charcrandom_u32() % 1000000; /* * this gives better @@ -1509,7 +1460,7 @@ void state_reboot (cpp) * from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER, * so pick an xid now. */ - client -> xid = random (); + client -> xid = charcrandom_u32(); /* * Make a DHCPREQUEST packet, and set @@ -1556,7 +1507,7 @@ void state_init (cpp) /* We've received an OFFER and it has been DECLINEd by dhclient-script. * wait for a random time between 1 and backoff_cutoff seconds before * trying again. */ - tv . tv_sec = cur_time + ((1 + (random() >> 2)) % client->config->backoff_cutoff); + tv . tv_sec = cur_time + ((1 + (charcrandom_u32() >> 2)) % client->config->backoff_cutoff); tv . tv_usec = 0; add_timeout(&tv, send_discover, client, 0, 0); } @@ -1770,7 +1721,7 @@ void dhcpack (packet) /* Now introduce some randomness to the renewal time: */ if (client->new->renewal <= ((TIME_MAX / 3) - 3)) client->new->renewal = (((client->new->renewal * 3) + 3) / 4) + - (((random() % client->new->renewal) + 3) / 4); + (((charcrandom_u32() % client->new->renewal) + 3) / 4); /* Same deal with the rebind time. */ oc = lookup_option (&dhcp_universe, client -> new -> options, @@ -1876,7 +1827,7 @@ void bind_lease (client) /* Set up a timeout to start the renewal process. */ tv.tv_sec = client->active->renewal; tv.tv_usec = ((client->active->renewal - cur_tv.tv_sec) > 1) ? - random() % 1000000 : cur_tv.tv_usec; + charcrandom_u32() % 1000000 : cur_tv.tv_usec; add_timeout(&tv, state_bound, client, 0, 0); log_info("bound to %s -- renewal in %ld seconds.", @@ -2699,12 +2650,12 @@ void send_discover (cpp) if (!client->interval) client->interval = client->config->initial_interval; else - client->interval += random() % (2 * client->interval); + client->interval += charcrandom_u32() % (2 * client->interval); /* Don't backoff past cutoff. */ if (client->interval > client->config->backoff_cutoff) client->interval = (client->config->backoff_cutoff / 2) - + (random() % client->config->backoff_cutoff); + + (charcrandom_u32() % client->config->backoff_cutoff); } else if (!client->interval) client->interval = client->config->initial_interval; @@ -2762,7 +2713,7 @@ void send_discover (cpp) * in a sub-second DOS ttck. */ tv.tv_sec = cur_tv.tv_sec + client->interval; - tv.tv_usec = client->interval > 1 ? random() % 1000000 : cur_tv.tv_usec; + tv.tv_usec = client->interval > 1 ? charcrandom_u32() % 1000000 : cur_tv.tv_usec; add_timeout(&tv, send_discover, client, 0, 0); } @@ -2815,7 +2766,7 @@ void state_panic (cpp) tv.tv_sec = client->active->renewal; tv.tv_usec = ((client->active->renewal - cur_time) > 1) ? - random() % 1000000 : + charcrandom_u32() % 1000000 : cur_tv.tv_usec; add_timeout(&tv, state_bound, client, 0, 0); } else { @@ -2874,9 +2825,9 @@ void state_panic (cpp) script_go (client); client -> state = S_INIT; tv.tv_sec = cur_tv.tv_sec + ((client->config->retry_interval + 1) / 2 + - (random() % client->config->retry_interval)); + (charcrandom_u32() % client->config->retry_interval)); tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ? - random() % 1000000 : cur_tv.tv_usec; + charcrandom_u32() % 1000000 : cur_tv.tv_usec; add_timeout(&tv, state_init, client, 0, 0); go_daemon (); } @@ -2960,8 +2911,8 @@ void send_request (cpp) if (!client -> interval) client -> interval = client -> config -> initial_interval; else { - client -> interval += ((random () >> 2) % - (2 * client -> interval)); + client -> interval += ((charcrandom_u32() >> 2) % + (2 * client->interval)); } /* Don't backoff past cutoff. */ @@ -2969,7 +2920,7 @@ void send_request (cpp) client -> config -> backoff_cutoff) client -> interval = ((client -> config -> backoff_cutoff / 2) - + ((random () >> 2) % + + ((charcrandom_u32() >> 2) % client -> config -> backoff_cutoff)); /* If the backoff would take us to the expiry time, just set the @@ -3076,7 +3027,7 @@ void send_request (cpp) tv.tv_sec = cur_tv.tv_sec + client->interval; tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ? - random() % 1000000 : cur_tv.tv_usec; + charcrandom_u32() % 1000000 : cur_tv.tv_usec; add_timeout(&tv, send_request, client, 0, 0); } @@ -3545,7 +3496,7 @@ void make_discover (client, lease) /* Assumes hw_address is known, otherwise a random value may result */ client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; - client -> packet.xid = random (); + client -> packet.xid = charcrandom_u32(); client -> packet.secs = 0; /* filled in by send_discover. */ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always)) @@ -3760,7 +3711,7 @@ void make_release (client, lease) /* Assumes hw_address is known, otherwise a random value may result */ client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; - client -> packet.xid = random (); + client -> packet.xid = charcrandom_u32(); client -> packet.secs = 0; client -> packet.flags = 0; memcpy (&client -> packet.ciaddr, @@ -4881,7 +4832,7 @@ void do_release(client) #endif /* Pick a random xid. */ - client -> xid = random (); + client -> xid = charcrandom_u32(); /* is there even a lease to release? */ if (client -> active) { --- dhcp-4.3.4/client/Makefile.am.random 2016-09-28 12:29:47.486938952 +0300 +++ dhcp-4.3.4/client/Makefile.am 2016-09-28 12:40:47.249352734 +0300 @@ -14,6 +14,6 @@ dhclient_SOURCES = clparse.c dhclient.c scripts/netbsd scripts/nextstep scripts/openbsd \ scripts/solaris scripts/openwrt dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(CAPNG_LDADD) \ - $(BIND9_LIBDIR) -lirs-export -ldns-export -lisccfg-export -lisc-export + $(BIND9_LIBDIR) -lirs-export -ldns-export -lisccfg-export -lisc-export -lcharcrandom man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5 EXTRA_DIST = $(man_MANS)