With reference to my earlier post about Hefferlump Traps,
and after further reflection, I'd like to propose the
following one-line patch to the file "fil.c":
change:
if (pass & FR_QUICK)
to:
if ((pass & FR_QUICK) && (skip == 0))
this line is about 6 or 7 lines (depending on the version of
IPFilter) before the end if the function "fr_scanlist"; and
applies to all recent versions 3.4 and the alpha version 4.
The net effect should be that:
* stopping because of a "quick" tag in a "skip" rule would
be delayed until the "skip" process had finished skipping
the subsequent rules -- but then such a "quick" tag is
ignored in any case because the rule flags are not copied
to the "pass" variable from the "passt" variable (which in
turn had been ser from the "fr->fr_flags" field in the rule);
the net effect is a small processor overhead (unless the
skip count and rule grour were *very* large)
* stopping because of an inherited "quick" tag on a group head
rule that entered a group that did not reset the "pass"
variable before encountering a "skip" rule would be delayed
while the "skip" was skipping; thus leaving the situation
as if the "skip" rule and those skipped had not been
present in the rule group
* the effect with "log" rules would not be changed
The last point is that this change gives minimum effects;
I personally think that a change that made "log" (only)
rules behave the same way as "skip" rules would probably
also remove another hefferlump trap (not just the one I
fell into). This change would require the insertion of
" && (passt & FR_LOGMASK) != FR_LOG)" into the patched
line just before the last ")". Alternativly, the code
could be modified in two places to note (in a local
variable) that the "pass = passt" statement had been
executed and to only test the "FR_QUICK" flag if it
had (been executed). Yet another variation would be
to test and remember the "FR_QUICK" flag *at the point
that the "pass = passt" statement is written* and to
then test that memory instead of "(pass & FR_QUICK)"
at the end of the for-loop. These variations are all
equivalent in effect and mainly a matter of style;
personally I prefer the last because it most clearly
expresses the idea that the "quick" tag only has an
effect on a rule that both matches (of course!) *and*
*changes the saved flags*. This would come down to,
in the "fr_scanlist" function in "fil.c", making the
following changes:
* at the top changing:
int rulen, portcmp, off, logged, skip;
to:
int rulen, portcmp, off, logged, skip, quick;
* in the middle changing:
pass = passt;
to:
pass = passt; quick = pass & FR_QUICK;
* near the end changing:
if (pass & FR_QUICK)
to:
if (quick)
Comments, anyone, Darren?
If there are no objections that convince me it's a bad
idea I'll test it and let the list know what happens.
If it works as I expect do we think this would be a
good patch to include in the master sources?
--
David Pick