[Bug 1332] New: Time-matching extension (--match time) broken by timestamping changes in kernel 4.20 and later

bugzilla-daemon at netfilter.org bugzilla-daemon at netfilter.org
Thu Apr 4 18:49:36 CEST 2019


https://bugzilla.netfilter.org/show_bug.cgi?id=1332

            Bug ID: 1332
           Summary: Time-matching extension (--match time) broken by
                    timestamping changes in kernel 4.20 and later
           Product: netfilter/iptables
           Version: unspecified
          Hardware: x86_64
                OS: All
            Status: NEW
          Severity: normal
          Priority: P5
         Component: ip_tables (kernel)
          Assignee: netfilter-buglog at lists.netfilter.org
          Reporter: stuben at iki.fi

Changes made to socket buffer timestamping (starting in kernel 4.20) will break
the functionality of the time-matching extension for iptables. Specifically,
the kernel patch called "tcp: provide earliest departure time in skb->tstamp"
[1] will result in the 'skb->tstamp' NOT being zeroed before entering the IP
stack. This change was introduced (in "net/ipv4/tcp_output.c") with the
following patch:
- /* Our usage of tstamp should remain private */
- skb->tstamp = 0;
+ /* Leave earliest departure time in skb->tstamp (skb->skb_mstamp_ns) */

Now that the timestamp no longer is cleared, this will end up causing incorrect
matching in function 'time_mt()' (in "net/netfilter/xt_time.c"). The "problem"
is present in the following two lines of code:
if (skb->tstamp == 0)
   __net_timestamp((struct sk_buff *)skb);

The above code will check if the packet already has a timestamp or not. If the
timestamp is missing, then the packet is timestamped with the current time. All
subsequent time matching calculations then assume that the packet's timestamp
is relative to the UNIX epoch (CLOCK_REALTIME reference). This all works fine,
as long as the timestamp explicitly has been set in xt_time. But the same
assumption on clock reference might not hold, if the packet comes in
pre-timestamped. And this is exactly what is happening in kernel 4.20.x and
later. Here the packets come in with a timestamp but that timestamp is not
based on current time but rather on CLOCK_MONOTONIC reference (i.e., time since
system boot).

I have verified this problem on kernel versions 4.19.6 (works) and 4.20.17
(broken). I have used prebuilt kernels for Fedora, but I do not think this is a
distribution specific problem. iptables is at version 1.8.0.

Steps to reproduce:
1) flush/delete all iptables rules and set all chains to ACCEPT
2) add a rule with time matching (e.g, 'iptables -A OUTPUT -d example.com
--match time --timestart <five minutes ago UTC> --timestop <five minutes in the
future UTC> -j DROP')
3) verify that packets to example.com are correctly dropped on 4.19.6
4) verify that packets to example.com are NOT dropped on 4.20.17
5) reintroduce 'skb->tstamp = 0;' in "net/ipv4/tcp_output.c", recompile kernel
4.20.17, and verify that packets now are being correctly dropped

I am not an expert on kernel internals and timestamping so I guess you need to
decide on how to fix this. A quick and dirty fix could be to never rely on
packet timestamps but always use current time as a matching reference.

[1]
https://github.com/torvalds/linux/commit/d3edd06ea8ea9e03de6567fda80b8be57e21a537#diff-2122118b70cbae1a5831191239717312

-- 
You are receiving this mail because:
You are watching all bug changes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.netfilter.org/pipermail/netfilter-buglog/attachments/20190404/5cf91ed8/attachment.html>


More information about the netfilter-buglog mailing list