rdr pass for proto tcp sometimes creates states with expire time zero and so breaking connections

Kristof Provost kristof at sigsegv.be
Sat Oct 27 17:44:40 UTC 2018


On 27 Oct 2018, at 5:22, Andreas Longwitz wrote:
> Thanks very much for answer especially for the hint to openbsd.
>
>> I wonder if there’s an integer overflow in the of_state_expires()
>> calculation.
>> The OpenBSD people have a cast to u_int64_t in their version:
>>
>> |timeout = (u_int64_t)timeout * (end - states) / (end - start);
>> |
>>
>> Perhaps this would fix your problem? (Untested, not even compiled)
>>
>> |        if (end && states > start && start < end) {
>>                 if (states < end) {
>>                     timeout = (uint64_t)timeout * (end - states) / 
>> (end - start);
>>                         return (state->expire + timeout;
>>                 }
>>                 else
>>                         return (time_uptime);
>>         }
>>         return (state->expire + timeout);
>
> I can confirm the patch of the openbsd people adding the uint64_t cast
> makes sense. If
>         timeout * (end - states)
> becomes bigger than UINT32_MAX (I am on i386) the cast prevents the
> overflow of this product and the result of the adaptive calculation 
> will
> always be correct.
>
> Example: start=6000, end=12000, timeout=86400 * 5 (5 days), states=100
>          result 140972, result with cast patch 856800.
>
> In the problem I have reported for states of "rdr pass" rules I see
> start=6000, end=12000, timeout=86400 and (obviously erroneous, 
> probably
> negative) states=0xffffffd0.
>
I have no idea how that can happen. Just to make sure I understand: you 
know that states is negative here because of a printf() or SDT addition 
in pf_expire_states(), right?

> Further the counter variable for states_cur of pf_default_rule is
> used für all "rdr/nat/binat pass" rules together. This was a little 
> bit
> suprising for me, but I think this is intended behaviour. Correct ?
>
Yes.

> Are there any hints why the counter pf_default_rule->states_cur
> could get a negative value ?
>
I’m afraid I have no idea right now.

Best regards,
Kristof


More information about the freebsd-pf mailing list