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
_______________________________________________
freebsd-pf@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-pf
To unsubscribe, send any mail to "freebsd-pf-unsubscr...@freebsd.org"