[Dnsmasq-discuss] lease->expires overflows, causes infinite loop
Simon Kelley
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
> 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.
>
> 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
in practice.
>
> 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
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
>
More information about the Dnsmasq-discuss
mailing list