The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d39d5ee2d67f61abc890b51973b5c4a0c81d6647

commit d39d5ee2d67f61abc890b51973b5c4a0c81d6647
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2021-02-25 08:50:57 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2021-05-25 13:26:27 +0000

    pf tests: Test cases for fragment reassembly
    
    Obtained from:  Alexander Bluhm, OpenBSD
---
 tests/sys/netpfil/pf/Makefile            |  8 +++
 tests/sys/netpfil/pf/frag-overindex.py   | 82 ++++++++++++++++++++++++++++++
 tests/sys/netpfil/pf/frag-overlimit.py   | 87 ++++++++++++++++++++++++++++++++
 tests/sys/netpfil/pf/frag-overreplace.py | 84 ++++++++++++++++++++++++++++++
 tests/sys/netpfil/pf/fragcommon.py       | 52 +++++++++++++++++++
 tests/sys/netpfil/pf/fragmentation.sh    | 83 ++++++++++++++++++++++++++++++
 6 files changed, 396 insertions(+)

diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile
index 2478cefbc4a6..b43a0a5a77b3 100644
--- a/tests/sys/netpfil/pf/Makefile
+++ b/tests/sys/netpfil/pf/Makefile
@@ -31,9 +31,17 @@ ATF_TESTS_SH+=       altq \
 ${PACKAGE}FILES+=      CVE-2019-5597.py \
                        CVE-2019-5598.py \
                        echo_inetd.conf \
+                       fragcommon.py \
+                       frag-overindex.py \
+                       frag-overlimit.py \
+                       frag-overreplace.py \
                        utils.subr
 
 ${PACKAGE}FILESMODE_CVE-2019-5597.py=  0555
 ${PACKAGE}FILESMODE_CVE-2019-5598.py=  0555
+${PACKAGE}FILESMODE_fragcommon.py=     0555
+${PACKAGE}FILESMODE_frag-overindex.py= 0555
+${PACKAGE}FILESMODE_frag-overlimit.py= 0555
+${PACKAGE}FILESMODE_frag-overreplace.py=       0555
 
 .include <bsd.test.mk>
diff --git a/tests/sys/netpfil/pf/frag-overindex.py 
b/tests/sys/netpfil/pf/frag-overindex.py
new file mode 100644
index 000000000000..594eb9efe39d
--- /dev/null
+++ b/tests/sys/netpfil/pf/frag-overindex.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: ISC
+#
+# Copyright (c) 2012-2021 Alexander Bluhm <bl...@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from fragcommon import *
+
+#                               index boundary 4096 |
+# |--------------|
+#                 ....
+#                     |--------------|
+#                                              |XXXX-----|
+#                                    |--------------|
+#
+# this should trigger "frag index %d, new %d" log in kernel
+
+def send(src, dst, send_if, recv_if):
+       pid = os.getpid()
+       eid = pid & 0xffff
+       payload = b"ABCDEFGHIJKLMNOP"
+       dummy = b"01234567"
+       fragsize = 64
+       boundary = 4096
+       fragnum = int(boundary / fragsize)
+       packet = sp.IP(src=src, dst=dst)/ \
+                       sp.ICMP(type='echo-request', id=eid)/ \
+                       (int((boundary + 8) / len(payload)) * payload)
+       frag = []
+       fid = pid & 0xffff
+       for i in range(fragnum - 1):
+               frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+                       frag=(i * fragsize) >> 3, flags='MF') /
+                       bytes(packet)[20 + i * fragsize:20 + (i + 1) * 
fragsize])
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary - 8) >> 3) /
+               (dummy + bytes(packet)[20 + boundary:20 + boundary + 8]))
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary - fragsize) >> 3, flags='MF') /
+               bytes(packet)[20 + boundary - fragsize:20 + boundary])
+       eth = []
+       for f in frag:
+               eth.append(sp.Ether() / f)
+
+       if os.fork() == 0:
+               time.sleep(1)
+               for e in eth:
+                       sp.sendp(e, iface=send_if)
+                       time.sleep(0.001)
+               os._exit(0)
+
+       ans = sp.sniff(iface=recv_if, timeout=5)
+       print(ans)
+       for a in ans:
+               a.show()
+               if a and a.type == sp.ETH_P_IP and \
+                               a.payload.proto == 1 and \
+                               a.payload.frag == 0 and \
+                               sp.icmptypes[a.payload.payload.type] == 
'echo-reply':
+                       id = a.payload.payload.id
+                       print("id=%#x" % (id))
+                       if id != eid:
+                               print("WRONG ECHO REPLY ID")
+                               sys.exit(2)
+                       sys.exit(0)
+       print("NO ECHO REPLY")
+       exit(1)
+
+if __name__ == '__main__':
+       main(send)
diff --git a/tests/sys/netpfil/pf/frag-overlimit.py 
b/tests/sys/netpfil/pf/frag-overlimit.py
new file mode 100644
index 000000000000..e25ebf5b0dcd
--- /dev/null
+++ b/tests/sys/netpfil/pf/frag-overlimit.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: ISC
+#
+# Copyright (c) 2012-2021 Alexander Bluhm <bl...@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from fragcommon import *
+from itertools import chain
+
+#                               index boundary 4096 |
+# |--------------|
+#                 ....
+#                     |--------------|
+#                                                   |--------------|
+#                                                                   ....----|
+#                                              |XXXX-----|
+#                                    |--------------|
+
+# this should trigger "fragment requeue limit exceeded" log in kernel
+
+def send(src, dst, send_if, recv_if):
+       pid = os.getpid()
+       eid = pid & 0xffff
+       payload = b"ABCDEFGHIJKLMNOP"
+       dummy = b"01234567"
+       fragsize = 64
+       boundary = 4096
+       fragnum= int(boundary / fragsize)
+       packet = sp.IP(src=src, dst=dst)/ \
+                       sp.ICMP(type='echo-request', id=eid)/ \
+                       (int((boundary + boundary) / len(payload)) * payload)
+       frag = []
+       fid = pid & 0xffff
+       for i in chain(range(fragnum - 1), range(fragnum, fragnum + fragnum - 
1)):
+               frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+                       frag=(i * fragsize) >> 3, flags='MF') /
+                       bytes(packet)[20 + i * fragsize:20 + (i + 1) * 
fragsize])
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary + boundary - fragsize) >> 3) /
+               bytes(packet)[20 + boundary + boundary - fragsize:])
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary - 8) >> 3, flags='MF')/
+               (dummy + bytes(packet)[20 + boundary:20 + boundary + 8]))
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary - fragsize) >> 3, flags='MF') /
+               bytes(packet)[20 + boundary - fragsize:20 + boundary])
+       eth = []
+       for f in frag:
+               eth.append(sp.Ether() / f)
+
+       if os.fork() == 0:
+               time.sleep(1)
+               for e in eth:
+                       sp.sendp(e, iface=send_if)
+                       time.sleep(0.001)
+               os._exit(0)
+
+       ans = sp.sniff(iface=recv_if, timeout=10, filter=
+                       "ip and src " + dst + " and dst " + src + " and icmp")
+       for a in ans:
+               if a and a.type == ETH_P_IP and \
+                               a.payload.proto == 1 and \
+                               a.payload.frag == 0 and \
+                               sp.icmptypes[a.payload.payload.type] == 
'echo-reply':
+                       id = a.payload.payload.id
+                       print("id=%#x" % (id))
+                       if id != eid:
+                               print("WRONG ECHO REPLY ID")
+                               sys.exit(2)
+                       print("ECHO REPLY")
+                       sys.exit(1)
+       sys.exit(0)
+
+if __name__ == '__main__':
+       main(send)
diff --git a/tests/sys/netpfil/pf/frag-overreplace.py 
b/tests/sys/netpfil/pf/frag-overreplace.py
new file mode 100644
index 000000000000..ff9184243a1d
--- /dev/null
+++ b/tests/sys/netpfil/pf/frag-overreplace.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: ISC
+#
+# Copyright (c) 2012-2021 Alexander Bluhm <bl...@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from fragcommon import *
+
+#                               index boundary 4096 |
+# |--------------|
+#                 ....
+#                     |--------------|
+#                                              |XXXX-----|
+#                                    |--------------|
+#                                                   |--------------|
+
+# this should trigger "frag tail overlap %d" and "frag head overlap %d"
+
+def send(src, dst, send_if, recv_if):
+       pid = os.getpid()
+       eid = pid & 0xffff
+       payload = b"ABCDEFGHIJKLMNOP"
+       dummy = b"01234567"
+       fragsize = 1024
+       boundary = 4096
+       fragnum = int(boundary / fragsize)
+       packet = sp.IP(src=src, dst=dst)/ \
+                       sp.ICMP(type='echo-request', id=eid)/ \
+                       (int((boundary + fragsize) / len(payload)) * payload)
+       frag = []
+       fid = pid & 0xffff
+
+       for i in range(fragnum - 1):
+               frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+                       frag=(i * fragsize) >> 3, flags='MF') /
+                       bytes(packet)[20 + i * fragsize:20 + (i + 1) * 
fragsize])
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary - 8) >> 3, flags='MF') /
+               (dummy + bytes(packet)[20 + boundary:20 + boundary + 8]))
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary - fragsize) >> 3, flags='MF') /
+               bytes(packet)[20 + boundary - fragsize:20 + boundary])
+       frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
+               frag=(boundary) >> 3)/bytes(packet)[20 + boundary:])
+
+       eth=[]
+       for f in frag:
+               eth.append(sp.Ether() / f)
+
+       if os.fork() == 0:
+               time.sleep(1)
+               for e in eth:
+                       sp.sendp(e, iface=send_if)
+                       time.sleep(0.001)
+               os._exit(0)
+
+       ans = sp.sniff(iface=recv_if, timeout=3, filter="")
+       for a in ans:
+               if a and a.type == sp.ETH_P_IP and \
+                               a.payload.proto == 1 and \
+                               a.payload.frag == 0 and \
+                               sp.icmptypes[a.payload.payload.type] == 
'echo-reply':
+                       id=a.payload.payload.id
+                       if id != eid:
+                               print("WRONG ECHO REPLY ID")
+                               sys.exit(2)
+                       sys.exit(0)
+       print("NO ECHO REPLY")
+       sys.exit(1)
+
+if __name__ == '__main__':
+       main(send)
diff --git a/tests/sys/netpfil/pf/fragcommon.py 
b/tests/sys/netpfil/pf/fragcommon.py
new file mode 100644
index 000000000000..2bcd3989b420
--- /dev/null
+++ b/tests/sys/netpfil/pf/fragcommon.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2021 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+import argparse
+import os
+import scapy.all as sp
+import sys
+import time
+
+def main(send):
+       parser = argparse.ArgumentParser("frag-overindex.py",
+               description="Fragmentation test tool")
+       parser.add_argument('--to', nargs=1,
+               required=True,
+               help='The address to send the fragmented packets to')
+       parser.add_argument('--fromaddr', nargs=1,
+               required=True,
+               help='The source address for the generated packets')
+       parser.add_argument('--sendif', nargs=1,
+               required=True,
+               help='The interface through which the packet(s) will be sent')
+       parser.add_argument('--recvif', nargs=1,
+               required=True,
+               help='The interface to expect the reply on')
+
+       args = parser.parse_args()
+
+       send(args.fromaddr[0], args.to[0], args.sendif[0], args.recvif[0])
diff --git a/tests/sys/netpfil/pf/fragmentation.sh 
b/tests/sys/netpfil/pf/fragmentation.sh
index 8b57bcf11487..8b16c9655d08 100644
--- a/tests/sys/netpfil/pf/fragmentation.sh
+++ b/tests/sys/netpfil/pf/fragmentation.sh
@@ -189,9 +189,92 @@ mtu_diff_cleanup()
        pft_cleanup
 }
 
+frag_common()
+{
+       name=$1
+
+       pft_init
+
+       epair=$(vnet_mkepair)
+       vnet_mkjail alcatraz ${epair}a
+
+       ifconfig ${epair}b inet 192.0.2.1/24 up
+       jexec alcatraz ifconfig ${epair}a 192.0.2.2/24 up
+
+       jexec alcatraz pfctl -e
+       pft_set_rules alcatraz \
+               "scrub all fragment reassemble"
+
+       # Sanity check
+       atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+
+       atf_check -s exit:0 -o ignore $(atf_get_srcdir)/frag-${1}.py \
+               --to 192.0.2.2 \
+               --fromaddr 192.0.2.1 \
+               --sendif ${epair}b \
+               --recvif ${epair}b
+}
+
+atf_test_case "overreplace" "cleanup"
+overreplace_head()
+{
+       atf_set descr 'ping fragment that overlaps fragment at index boundary 
and replace it'
+       atf_set require.user root
+       atf_set require.progs scapy
+}
+
+overreplace_body()
+{
+       frag_common overreplace
+}
+
+overreplace_cleanup()
+{
+       pft_cleanup
+}
+
+atf_test_case "overindex" "cleanup"
+overindex_head()
+{
+       atf_set descr 'ping fragment that overlaps the first fragment at index 
boundary'
+       atf_set require.user root
+       atf_set require.progs scapy
+}
+
+overindex_body()
+{
+       frag_common overindex
+}
+
+overindex_cleanup()
+{
+       pft_cleanup
+}
+
+atf_test_case "overlimit" "cleanup"
+overlimit_head()
+{
+       atf_set descr 'ping fragment at index boundary that cannot be requeued'
+       atf_set require.user root
+       atf_set require.progs scapy
+}
+
+overlimit_body()
+{
+       frag_common overlimit
+}
+
+overlimit_cleanup()
+{
+       pft_cleanup
+}
+
 atf_init_test_cases()
 {
        atf_add_test_case "too_many_fragments"
        atf_add_test_case "v6"
        atf_add_test_case "mtu_diff"
+       atf_add_test_case "overreplace"
+       atf_add_test_case "overindex"
+       atf_add_test_case "overlimit"
 }
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to