[Dnsmasq-discuss] lease->expires overflows, causes infinite loop
simon at thekelleys.org.uk
Wed Jan 22 10:56:48 GMT 2014
On 22/01/14 00:52, Daniel Mentz wrote:
> I'm having this problem where dnsmasq gets into an infinite loop. This
> is what my lease file looks like (only the MAC addresses have been
> changed to protect the innocent)
> 2147483647 a0:0b:ba:00:90:91 192.168.42.79 android-67a44277e5118e11
> The value for lease->expires is Jan 19 2038 which is the end of a
> signed time_t on a 32 bit platform. I'm not sure how the value got
> there, but I certainly did not manually manipulate this file. It could
> have to do with my clock jumping from 1970 to 2014.
> Now, in lease_update_file(), it executes this code:
> next_event = lease->expires + 10;
OK, I looked a bit more. The 10s slop is redundant. I think the code
originally called alarm() directly and it was to ensure that next_event
was always in the future. send_alarm() handles that now: the analogous
code in periodic_ra() and periodic_slaac doesn't have the 10s slop.
The best solution to the looping problem it therefore to remove the + 10
There needs to be a check in lease_set_expires() for when the expiry
time overflows too, and strictly also in the ra and slaac systems, but
they only even add bounded small numbers to "now" so that's not needed
> which causes the time_t value to overflow. The result is December 13
> 1901 which will cause the event to trigger immediately. However,
> lease_prune() does not suffer from this overflow problem which is why
> the lease does not get removed, and we end up in an infinite loop.
> We are using dnsmasq 2.67.
> Can anybody confirm this problem?
> Now that I look at it more closely, it occurred to me that
> lease_update_file() coerces lease->expires from a signed type to an
> unsigned type:
> ourprintf(&err, "%lu ", (unsigned long)lease->expires);
> Let's assume lease->expires is negative (before Jan 1 1970), then this
> coercion yields something that is bigger than LONG_MAX. When
> lease_init() reads this value back in with
> ei = atol(daemon->dhcp_buff3);
> atol() maxes out at LONG_MAX which could explain why I'm seeing this value.
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
More information about the Dnsmasq-discuss