[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