[Dnsmasq-discuss] lease->expires overflows, causes infinite loop

Simon Kelley simon at thekelleys.org.uk
Wed Jan 22 10:19:44 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
> 00:14:d1:22:aa:e6
>
> 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.

That's quite possible. There are times when the lease is calculated as a 
length/time/interval. A lease which expires in 2014 will translate to a 
very long lease when the time is 1970, and then adding that to the 
changed time in 2014 will result in a lease which busts the 2038 barrier.

If your real-time-clock is chronically broken, then you should consider 
building dnsmasq with the HAVE_BROKEN_RTC compile-time option. It 
behaves much better in the face of such insults if you do.
>
> Now, in lease_update_file(), it executes this code:
>
> next_event = lease->expires + 10;
>
> 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.
>

That all makes perfect sense. Sigh: I was hoping for at lease another 
decade before this came up. I'll add a check to at least avoid a nasty 
infinite loop here.

Cheers,

Simon



> _______________________________________________
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
>




More information about the Dnsmasq-discuss mailing list