From nobody Tue Feb 11 10:33:00 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ysd7c6vlLz5nN3H; Tue, 11 Feb 2025 10:33:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ysd7c45qHz3t8m; Tue, 11 Feb 2025 10:33:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739269980; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lD8eSk369hJqlohdvluWlW5k/apJnDbQSCbGHfGg564=; b=og9C24vwmijLhMmO6Q29/EnzJ0YlHwQR0fVqQSR+7C1GQxABhKTTQ0dYSbfarXGsQi77PT KU/o/xgNUBanHMvfR42sWViznPwdgn+/G2OpQv0cEZVZuErHuXQfUkp6LKiPM8j5UPLUvU DYgnebhctLI0Io1HDkunw5Qm5BKf+KHRr1zs0pI/J11PLpqxEMLm5EZk9IuBU4B7O9mzRl gCHCGO4HwxupJucvrHwU5fMc+fqTQ6zx4n8OlUsJOWZvyZ8rH3HasBMYaGnF8D5AFqIX45 RRFRfQU+4ZPer888eeuIM8fA1IKUPYznbh8E0eeSyQFvVGPaKiGBzQhAgavLaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739269980; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lD8eSk369hJqlohdvluWlW5k/apJnDbQSCbGHfGg564=; b=SYB7YjSQzq0hwNLJR3dE8GEC+nvEE6DJ3gFiT7Q6zCvG8NdCi0Y4/ee9zC7HfSbyhahrJl c/gZRumomvxOCAccjSviApawdo2Q1s0y0MJXnEl7QVHR1PaYWqDfkIwAEcnwpO6DUOzfCH PuDC25IjmFsBIVb8DsJjrN7nz5p7P+Nv9ZhhtH0iCM7mQlPz9qAOJEU/Jw/SUR0awrVl3f /3xnV+2bWMNRmxuUzZFM2FXsKlp8WTloAXFYWrNDfKtMJfumbL+cXCTNDkZrOX84jplFXm pjggK2LC5lJl73+rHEAH89XGmiNGCFE3jly+4gzCwLIT8ofKxi0ExUPgDqRyUg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1739269980; a=rsa-sha256; cv=none; b=TxVvrGwX8mkP+PsBrqW17R+O4ML/k5n41Yx5mt+UhT6wDGPkAKbwIuUbUvsTWZM6qjnyQJ iEMqoRpsshGE7F/O3kLSbk1USUUqMjxTjo/XMpgwvUWXZ5kI+Pu7gDUzr+zW6lgOpTkJml QnQqsuqd8BllEt6hab6ESmjA6CDfKK/BAswXjGUfauRji0A3xgoCJ+lTpt5qoiSa25iWJX pWlwtUyrZ46RTJKYgosxKt35zOuQfZmmzOnm5WdiCkVsDzRJ5JKSxiAUDTT5gmpHuvVrbc GLu4cylWJftHI6VWljhcL8/bGYJ7PAUrygHCuF6mz4ImLgcpDzvtfrBX5EGT7Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Ysd7c3Y3Rz17XL; Tue, 11 Feb 2025 10:33:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51BAX0uB043107; Tue, 11 Feb 2025 10:33:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51BAX0Dr043104; Tue, 11 Feb 2025 10:33:00 GMT (envelope-from git) Date: Tue, 11 Feb 2025 10:33:00 GMT Message-Id: <202502111033.51BAX0Dr043104@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: db100bd93036 - main - pf tests: add more fragmentation test cases List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: db100bd93036855c7688dc088b811dc7b660f51d Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=db100bd93036855c7688dc088b811dc7b660f51d commit db100bd93036855c7688dc088b811dc7b660f51d Author: Kristof Provost AuthorDate: 2025-02-04 13:06:33 +0000 Commit: Kristof Provost CommitDate: 2025-02-11 10:32:22 +0000 pf tests: add more fragmentation test cases Add more test cases for pf fragment hole counter. Also look into final fragment of echo reply and check total length of IP packet. MFC after: 1 week Obtained from: OpenBSD, bluhm , 640736615b Sponsored by: Rubicon Communications, LLC ("Netgate") --- tests/sys/netpfil/pf/Makefile | 4 ++ tests/sys/netpfil/pf/frag-adjhole.py | 58 +++++++++++++++++++++ tests/sys/netpfil/pf/frag-overhole.py | 83 ++++++++++++++++++++++++++++++ tests/sys/netpfil/pf/fragmentation_pass.sh | 38 ++++++++++++++ 4 files changed, 183 insertions(+) diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile index 2edd8e7d2026..8a24fae47dcb 100644 --- a/tests/sys/netpfil/pf/Makefile +++ b/tests/sys/netpfil/pf/Makefile @@ -71,6 +71,8 @@ ${PACKAGE}FILES+= CVE-2019-5597.py \ frag-overindex.py \ frag-overlimit.py \ frag-overreplace.py \ + frag-overhole.py \ + frag-adjhole.py \ pfsync_defer.py \ pft_ether.py \ pft_read_ipfix.py \ @@ -83,6 +85,8 @@ ${PACKAGE}FILESMODE_fragcommon.py= 0555 ${PACKAGE}FILESMODE_frag-overindex.py= 0555 ${PACKAGE}FILESMODE_frag-overlimit.py= 0555 ${PACKAGE}FILESMODE_frag-overreplace.py= 0555 +${PACKAGE}FILESMODE_frag-overhole.py= 0555 +${PACKAGE}FILESMODE_frag-adjhole.py= 0555 ${PACKAGE}FILESMODE_pfsync_defer.py= 0555 ${PACKAGE}FILESMODE_pft_ether.py= 0555 ${PACKAGE}FILESMODE_pft_read_ipfix.py= 0555 diff --git a/tests/sys/netpfil/pf/frag-adjhole.py b/tests/sys/netpfil/pf/frag-adjhole.py new file mode 100644 index 000000000000..99caf66617dd --- /dev/null +++ b/tests/sys/netpfil/pf/frag-adjhole.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2025 Alexander Bluhm + +from fragcommon import * + +# |--------| +# |--------| +# |-------| +# |----| + +def send(src, dst, send_if, recv_if): + pid = os.getpid() + eid = pid & 0xffff + payload = b"ABCDEFGHIJKLMNOP" * 2 + packet = sp.IP(src=src, dst=dst)/ \ + sp.ICMP(type='echo-request', id=eid) / payload + frag = [] + fid = pid & 0xffff + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + flags='MF') / bytes(packet)[20:36]) + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + frag=2, flags='MF') / bytes(packet)[36:52]) + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + frag=1, flags='MF') / bytes(packet)[28:44]) + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + frag=4) / bytes(packet)[52:60]) + eth=[] + for f in frag: + eth.append(sp.Ether()/f) + if os.fork() == 0: + time.sleep(1) + sp.sendp(eth, iface=send_if) + os._exit(0) + + ans = sp.sniff(iface=recv_if, timeout=3, filter= + "ip and src " + dst + " and dst " + src + " and icmp") + for a in ans: + if a and a.type == sp.ETH_P_IP and \ + a.payload.proto == 1 and \ + a.payload.frag == 0 and a.payload.flags == 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") + exit(2) + data = a.payload.payload.payload.load + print("payload=%s" % (data)) + if data == payload: + exit(0) + print("PAYLOAD!=%s" % (payload)) + exit(1) + print("NO ECHO REPLY") + exit(2) + +if __name__ == '__main__': + main(send) diff --git a/tests/sys/netpfil/pf/frag-overhole.py b/tests/sys/netpfil/pf/frag-overhole.py new file mode 100644 index 000000000000..91697b6b83c6 --- /dev/null +++ b/tests/sys/netpfil/pf/frag-overhole.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2025 Alexander Bluhm + +from fragcommon import * + +# index boundary 4096 | +# |--------------| +# .... +# |--------------| +# |----------| +# |XXXX----------| +# |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)) + 1) * payload) + packet_length = len(packet) + 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 - fragsize) >> 3, flags='MF')/ + bytes(packet)[20 + boundary - fragsize:20 + boundary - len(dummy)]) + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + frag=(boundary - len(dummy)) >> 3, flags='MF')/ + (dummy+bytes(packet)[20 + boundary:20 + boundary + fragsize])) + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + frag=(boundary - 8 - len(dummy)) >> 3, flags='MF')/ + (dummy+bytes(packet)[20 + boundary - 8:20 + boundary])) + frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid, + frag=(boundary + fragsize) >> 3)/bytes(packet)[20 + boundary + fragsize:]) + 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= + "ip and src " + dst + " and dst " + src + " and icmp") + 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 + print("id=%#x" % (id)) + if id != eid: + print("WRONG ECHO REPLY ID") + exit(2) + if a and a.type == sp.ETH_P_IP and \ + a.payload.proto == 1 and \ + a.payload.frag > 0 and \ + a.payload.flags == '': + length = (a.payload.frag << 3) + a.payload.len + print("len=%d" % (length)) + if length != packet_length: + print("WRONG ECHO REPLY LENGTH") + exit(1) + exit(0) + print("NO ECHO REPLY") + exit(1) + +if __name__ == '__main__': + main(send) diff --git a/tests/sys/netpfil/pf/fragmentation_pass.sh b/tests/sys/netpfil/pf/fragmentation_pass.sh index 68b078d42ddc..4e0665094ae6 100644 --- a/tests/sys/netpfil/pf/fragmentation_pass.sh +++ b/tests/sys/netpfil/pf/fragmentation_pass.sh @@ -354,6 +354,42 @@ overlimit_cleanup() pft_cleanup } +atf_test_case "overhole" "cleanup" +overhole_head() +{ + atf_set descr 'ping fragment at index boundary which modifies pf hole counter' + atf_set require.user root + atf_set require.progs scapy +} + +overhole_body() +{ + frag_common overhole +} + +overhole_cleanup() +{ + pft_cleanup +} + +atf_test_case "adjhole" "cleanup" +adjhole_head() +{ + atf_set descr 'overlapping ping fragments which modifies pf hole counter' + atf_set require.user root + atf_set require.progs scapy +} + +adjhole_body() +{ + frag_common adjhole +} + +adjhole_cleanup() +{ + pft_cleanup +} + atf_test_case "reassemble" "cleanup" reassemble_head() { @@ -618,6 +654,8 @@ atf_init_test_cases() atf_add_test_case "overreplace" atf_add_test_case "overindex" atf_add_test_case "overlimit" + atf_add_test_case "overhole" + atf_add_test_case "adjhole" atf_add_test_case "reassemble" atf_add_test_case "no_df" atf_add_test_case "reassemble_slowpath"