aboutsummaryrefslogtreecommitdiff
path: root/sys/netpfil/pf/pf.c
Commit message (Collapse)AuthorAgeFilesLines
* pf: fix handling unreassembled fragmentsKristof Provost4 days1-2/+2
| | | | | | | | | | | | | | If we handle a fragment and are configured not to reassemble it the pd->proto field will show the layer 4 protocol (i.e. UDP,TCP,SCTP,...) but pd->virtual_proto will show we're a fragment. In that case we also don't have the layer 4 checksum pointer. Have code that cares about L4 (e.g. NAT) check virtual_proto so it doesn't try to dereference a NULL pcksum field. PR: 288549 Reported by: Danilo Egea Gondolfo <danilo@FreeBSD.org> Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51722
* pf: also allocate ethernet anchors from a UMA zoneKristof Provost4 days1-0/+7
| | | | | | | As per the previous commit, ensure we can't endlessly allocate ethernet anchors. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: allocate pf_kanchor from a poolKristof Provost4 days1-0/+8
| | | | | | | | | | | | Add a pool for the allocation of the pf_anchor struct. It was possible to exhaust kernel memory by repeatedly calling pfioctl DIOCXBEGIN with different anchor names. OK bluhm@ Reported-by: syzbot+9dd98cbce69e26f0fc11@syzkaller.appspotmail.com Obtained from: OpenBSD, mbuhl <mbuhl@openbsd.org>, fa90ac5c78 Obtained from: OpenBSD, mbuhl <mbuhl@openbsd.org>, c259202341 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: return errors from pf_route() and pf_route6()Kristof Provost5 days1-19/+47
| | | | | | | | | | | | | | | | If we fail to route the packet in pf_route()/pf_route6() (e.g. because it hit the TTL limit) we free the mbuf. If that packet is an SCTP packet that establishes extra (i.e. multihome) states we have a queued job to handle that. These jobs reference the now freed mbuf. Pass the error from pf_route()/pf_route6() on, so that pf_sctp_multihome_delayed() doesn't attempt to use the invalid mbuf pointer (or establishes states for a packet we're not passing). PR: 288274 Reported by: Robert Morris <rtm@lcs.mit.edu> Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51627
* pf: Use different address family for source and redirection addressKajetan Staszkiewicz8 days1-8/+13
| | | | | | | | | | | | | | | | | | | | The function pf_map_addr() and source tracking operate on a single address family. This made sense before introducing address family translation. When combining af-to with route-to or with sticky-address, the next-hop or the NAT address are of different address family than the source address. For example in NAT64 scenaro an IPv6 source address is translated to an IPv4 address and routed over IPv4 gateway. Make source nodes dual-AF, that is have a separate source AF and redirection AF. Store route AF in struct pf_kstate, export it to pfctl. When loading rules with redirection pools with pfctl store address family of each address. When printing states don't deduce next-hop's address family from af-to, use the one stored in state. Reviewed by: kp Approved by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D51659
* pf: remove incorrect __unused annotationKristof Provost11 days1-1/+1
| | | | Sponsored by: Rubicon Communications, LLC ("Netgate")
* kern: adopt the cr_gid macro for cr_groups[0] more widelyKyle Evans2025-07-241-2/+2
| | | | | | | | | | | | | | | | A future change may split cr_gid out of cr_groups[0] so that there's a cleaner separation between the supplemental groups and the effective group. Do the mechanical conversion where we can, and drop some comments where we need further work because some assumptions about cr_gid == cr_groups[0] have been made. This should not be a functional change, but downstreams and other out-of-tree code are advised to investigate their usage of cr_groups sooner rather than later, as a future change will render assumptions about these two being equivalent harmful. Reviewed by: asomers, kib, olce Differential Revision: https://reviews.freebsd.org/D51153
* pf: unify DPFPRINTF definitionsKristof Provost2025-07-231-68/+67
| | | | | | | | | | | | | We define DPFPRINTF() in a few different versions in most pf source files. Move to one definition in pfvar.h and use that one everywhere. While here change it to add an endline, as OpenBSD does, so we consistently end all logs with an endline. Also add a static probe point to ease future debugging. This way we can detect log evens even when logging is disabled, and extract more information (e.g. stack traces, frequency, ...). Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: handle truncated IP options in ICMPKristof Provost2025-07-231-0/+7
| | | | | | | | | | In pf the kernel paniced if IP options in packet within ICMP payload were truncated. Drop such packets instead. Reported-by: syzbot+91abd3aa2fdfe900f9ce@syzkaller.appspotmail.com OK sashan@ claudio@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 0271abd8e4 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Make pf(4) more paranoid about IGMP/MLP messages.Kristof Provost2025-07-231-1/+22
| | | | | | | | | | | MLD/IGMP messages with ttl other than 1 will be discarded. Also MLD messages with other than link-local source address will be discarded. IGMP messages with destination address other than multicast class will be discarded. feedback and OK bluhm@, cluadio@ Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 5f7837b6d7 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: accept IP options for IGMP and ICMP6 MLDKristof Provost2025-07-231-18/+114
| | | | | | | | | | | | | | | IGMP and ICMP6 MLD packets always have the router alert option set. pf blocked IPv4 options and IPv6 option header by default. This forced users to set allow-opts in pf rules. Better let multicast work by default. Detect router alerts by parsing IP options and hop by hop headers. If the packet has only this option and is a multicast control packet, do not block it due to bad options. tested by otto@; OK sashan@ Relnotes: yes Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 214dd8280c Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: run Jumbogram check before we walk the headersKristof Provost2025-07-231-9/+9
| | | | | | | | | While it is safe to run pf_walk_header6() on a packet with a 0 ip6_plen we're better off doing this check first. It's more obviously correct, and it's a very simple check to reject a packet. Suggested by: emaste Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: move IPv4 packet length check upKristof Provost2025-07-231-6/+7
| | | | | | | Perform this check ("Do we have enough data for the IP length?") so it happens before normalisation. Sponsored by: Rubicon Communications, LLC ("Netgate")
* Revert "pf: remove unused argument from pf_send_icmp()"Kristof Provost2025-07-161-8/+8
| | | | | | | | This reverts commit ea97c397d75c3fd108b1bc033f39d3e6d41c7dfe. The rule is used in the ALTQ case, which I missed. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: add missing IPv6 length checkKristof Provost2025-07-161-0/+6
| | | | | | | | | | | | We failed to verify that the packet was long enough for the provided IPv6 packet length. This could result in us walking off the end of the mbuf and panicing. PR: 288224 Reported by: Robert Morris <rtm@lcs.mit.edu> Tested by: Robert Morris <rtm@lcs.mit.edu> Reviewed by: emaste Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51324
* pf: delay taking the rules lock in pf_test()Kristof Provost2025-07-161-9/+5
| | | | | | | | | | | | | | | | We don't need the rules lock to protect the mbuf, or even the kif. If an interface is removed (which is the only way for a kif to go away) we're not going to receive traffic on it. We can't delay taking the lock more, because pf_setup_pdesc() calls the normalisation code, which iterates the scrub rules. If we ever get rid of those (as OpenBSD has) it should be possible to delay taking the rules lock until we actually need to iterate of the rules. That is, we might be able to avoid taking it at all if we match an existing state. Reviewed by: glebius Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51329
* pf: remove unused argument from pf_send_icmp()Kristof Provost2025-07-151-8/+8
| | | | | | We never use the struct pf_krule, so remove that argument. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Don't run copies of packets made by dup-to through pf_test.Kristof Provost2025-07-151-0/+6
| | | | | | | | | | | | | | | | | dup-to is kind of like what you do with a span port, but is a bit more fine grained. it copies packets in a connection out an interface so that connection can be monitored. it doesnt make sense for pf to see the copied packets and try to match or create new states for them either. at best it needs config to stop pf seeing the copies (eg, set skip on $dup_to_tgt_if). at worst it breaks the connections you're monitoring because the states in pf get confused. found while discussing larger route-to changes on tech@. ok bluhm@ sashan@ Obtained from: OpenBSD, dlg <dlg@openbsd.org>, 670ae1ca2f Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: synproxy should be processing incoming SYN packets only.Kristof Provost2025-07-151-1/+1
| | | | | | | | | issue noticed by sthen@. fix discussed with bluhm@ and procter@ OK bluhm@, kn@, procter@ Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 4e62cf09d9 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Fix error handling when pf_map_addr() failsKajetan Staszkiewicz2025-07-131-4/+5
| | | | | | | | | | | | | | | | | When pf_map_addr() fails, for example for a NAT pool, we expect packet will not be forwarded. The error returned by pf_map_addr() has been ignored in pf_map_addr_sn(), though, causing packets being forwarded without NAT applied. Catch the error, return the error to caller, let the caller handle error counters for route-to pools just like it does for NAT pools. Add tests for NAT and route-to rules. Improve logging by not hardcoding function name and use __func__ instead. Reviewed by: kp Approved by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D50763
* pf: Don't access sk and nk before they are allocatedKajetan Staszkiewicz2025-07-121-1/+8
| | | | | | | | | | | | | | The NAT addresses are chosen during ruleset parsing. The new afto code stores post-nat addresses in nsaddr. The old nat code (also used for new nat-to rules) creates state keys and stores addresses in them. Ensure proper way of accessing the NAT addresses in case sticky-address is used for af-to rules. Reviewed by: kp Approved by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D50768
* pf: Don't return src node and hash from pf_map_addr_snKajetan Staszkiewicz2025-07-121-3/+1
| | | | | The function pf_map_addr_sn() already returns naddr and nkif, there is no need to return the source node too, it is redundant.
* pf: Use -1 to indicate an invalid uid/gid, not UID_MAX and GID_MAX.Kristof Provost2025-07-091-4/+4
| | | | | | | | This is clearer and more consistent with the rest of the kernel. OK deraadt@ sashan@ Obtained from: OpenBSD, millert <millert@openbsd.org>, d04cdf616e Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Remove useless macrosKristof Provost2025-07-041-76/+90
| | | | | | | | | These are just unhelpful case conversion. OK sashan henning Obtained from: OpenBSD, kn <kn@openbsd.org>, 492cf6614c Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: honor quick on anchor rulesKristof Provost2025-07-041-3/+4
| | | | | | | | | | | | Regression has been introduced in version 1.1024 (a 6.2 time frame). It's been discovered and reported by Fabian Mueller-Knapp. Fair amount of credit goes to kn@, benno@ and henning@ for pointing me to releveant section of pf.conf(5). Fabian and kn@ also did test the patch. OK kn@, henning@ Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 7e89334d42 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Honor quick on anchor rulesKristof Provost2025-07-031-0/+6
| | | | | | | | | | | | | | | | | | | | When evaluating the anchor's ruleset, prevent clobbering it's very own `quick' test result by blindly setting it. This makes the following pf.conf work as intended (packets would be blocked since `quick' had no effect): anchor quick { pass } block Broken since after 6.1 release as reported by Fabian Mueller-Knapp, thanks! OK henning sashan Obtained from: OpenBSD, kn <kn@openbsd.org>, b9014d31ce Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: trade few 'goto unlock: for 'break' in pf_test()Kristof Provost2025-06-301-4/+4
| | | | | | | OK mpi@, OK henning@, OK jca@ Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 18b958d7c9 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: remove STATE_LOOKUPKristof Provost2025-06-301-40/+74
| | | | | | | | | the STATE_LOOKUP macro made sense ages ago. It stopped making sense when we moved most of the functionality into a function. g/c the macro and just call the function. ok mpi jca Obtained from: OpenBSD, henning <henning@openbsd.org>, 4fc68ab0d1 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Refactor the six ways to find TCP options into one new function.Kristof Provost2025-06-271-104/+94
| | | | | | | | | | | As a result: - MSS and WSCALE option candidates must now meet their min type length. - 'max-mss' is now more tolerant of malformed option lists. These changes were immaterial to the live traffic I've examined. OK sashan@ mpi@ Obtained from: OpenBSD, procter <procter@openbsd.org>, 672fea2ccb Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: ensure max-pkt-size works on match rulesKristof Provost2025-06-271-3/+8
| | | | Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: add 'max-pkt-size'Kristof Provost2025-06-271-0/+8
| | | | | | | | Allow pf to limit packets to a specified maximum size. This applies to all packets, and if reassembly is enabled, looks at the reassembled size, not the size of individual fragments. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: fix regression in pflog outputKristof Provost2025-06-261-2/+13
| | | | | | | | | | | pf_match_rule() must remember current anchor before descents towards leaf. it must restore anchor as it ascents towards root. Bug pointed out and fix also tested by Matthias Pitzl from genua. OK bluhm@ Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 73e0536f0e Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: decrement TTL in pf_route(6)()Kristof Provost2025-06-261-1/+23
| | | | | | | | | | | | | | When pf(4) forwards incoming packets with route-to or reply-to, decrement the time-to-live or hop-limit field to prevent routing loops. Sending an ICMP time exceeded error makes traceroute work. For outgoing packets ip_forward() has already done this. OK visa@ sashan@ Add a test case for the above, and fix the nat64 tests to account for the nat64 router now decrementing the TTL. Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 18421856bb Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Use pf_send_icmp() consistently in pf_route()Kristof Provost2025-06-261-17/+15
| | | | | | | | | It sets the routing domain and other mbuf flags. In pf_route6() the bad packet counter and dup-to check were missing. OK visa@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 51a22f9bf3 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: disallow IPv6 routing header by defaultKristof Provost2025-06-261-0/+2
| | | | | | | | | | pf drops IPv4 packets with any options by default. For IPv6 the same is already done for options header. Add the routing extension header to the list that need "allow-opts" to pass. OK sashan@ visa@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, bfcbb272c6 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: drop neighbor discovery packets with the wrong hop limitKristof Provost2025-06-261-0/+8
| | | | | | | | | | | | RFC 4861 requires that all neighbor discovery packets have 255 in their IPv6 header hop limit field. Let pf drop neighbor solicitation, neighbor advertisement, router solicitation, router advertisement, and redirect ICMP6 packets that do not comply. This enforces that bogus packets cannot be routed when pf is enabled. OK mpi@ sashan@ benno@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 441055dec2 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: limit extra SCTP statesKristof Provost2025-06-251-0/+11
| | | | | | | | | | | For SCTP we create states for all combinations of endpoints, to allow multihoming to work. Malicious users could abuse this to fill our state table more easily than they otherwise could, because we create states between all combinations of endpoints. Limit this to no more than 8 extra endpoints for each side of the connection. MFC after: 2 weeks Sponsored by: Orange Business Services
* pf: add a generic packet rate matching filterKristof Provost2025-06-251-0/+11
| | | | | | | | | | | | | | | allows things like pass in proto icmp max-pkt-rate 100/10 all packets matching the rule in the direction the state was created are taken into consideration (typically: requests, but not replies). Just like with the other max-*, the rule stops matching if the maximum is reached, so in typical scenarios the default block rule would kick in then. with input from Holger Mikolon ok mikeb Obtained from: OpenBSD, henning <henning@openbsd.org>, 5a4ae9a9cb Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50798
* pf: use counter_rate() for rate checkingKristof Provost2025-06-251-27/+15
| | | | | | | | | | This has the advantage of not requiring a lock. The current src node code runs the rate check under a lock, so this won't immediately improve performance. This prepares the way for future work, introducing packet rate matching on rules, where the lack of lock will be important. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50797
* pf: fix NOINET6 buildGleb Smirnoff2025-06-101-0/+2
|
* pf: align option handling for IPv4 and IPv6Kristof Provost2025-06-061-4/+7
| | | | | | | | | | | | Block IPv6 packets in pf(4) that have hop-by-hop options header or destination options header. Such packets can be passed by adding "allow-opts" to the rule. So IPv6 options are handled like their counterpart in IPv4 now. tested by benno@; OK henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, c50c83ac27 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50662
* pf: limit how many headers we look atKristof Provost2025-06-061-5/+13
| | | | | | | | | | | Limit the nested header chain for IPv6 extensions headers and for authentication headers in the IPv4 case. This prevents spending excessive cpu time on crafted packets. OK henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 2e5bc81177 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50659
* pf: use 'struct ah' for the AH extension header rather than 'struct ip6_ext'Kristof Provost2025-06-061-3/+5
| | | | | | | | | This fixes the build for NOINET6 kernels, but also more accurately reflects what we're doing. The first two fields are the same, so the only functional change is that we require slightly more data in the first fragment now. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50658
* pf: align IPv4 and IPv6 AH header handlingKristof Provost2025-06-061-11/+54
| | | | | | | | | | | | | | | | Pf was handling IPv4 and IPv6 differently regarding AH extension headers. pf_walk_header6() steps over it and detects the real protocol. So to implement a minimal header walking function pf_walk_header() for IPv4. It does the header checks and jumps over AH. Then pf does not understand AH as a protocol, it is just an extension that authenticates the packet. Move some header and option checks to pf_walk_header() for consistency with IPv6. This also improves the header check for IPv4 packets in ICMP payload. OK henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 22ef11432c Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50657
* pf: use struct pf_test_ctx as function argumentKristof Provost2025-06-021-81/+68
| | | | | | | Use the struct rather than passing individual fields as arguments. No functional change. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: remove unused argument from pf_get_translation()Kristof Provost2025-06-021-1/+1
| | | | | | No functional change. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: rework anchor handling to recurseKristof Provost2025-06-021-282/+275
| | | | | | | | | | | | | | | | - percpu anchor stacks we actually don't need to pre-allocate per_anchor_stack[], if we use a 'natural' recursion, when doing anchor tree traversal. O.K. mikeb@, mpi@ Extended because FreeBSD pf still has separate NAT rules processing, which also needed this change. Obtained from: OpenBSD, sashan <sashan@openbsd.org>, e236f0fa7b Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 5e4ad307dc Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50579
* pf: teach pf_build_tcp() about SACKKristof Provost2025-05-281-2/+12
| | | | | | | ok & with sashan Obtained from: OpenBSD, henning <henning@openbsd.org>, 01c3818b6b Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: refactor length check in pf_pull_hdr()Kristof Provost2025-05-281-13/+8
| | | | | | | | | Move the common length check in pf_pull_hdr() after the address family switch. This makes the specific calculation more obvious. OK claudio@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 9f98372a33 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: use __func__ rather than hardcoded function namesKristof Provost2025-05-091-9/+11
| | | | | | | | Replace function names with __func__ in debug prints to make grep happy. Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 68d5ab4417 Sponsored by: Rubicon Communications, LLC ("Netgate")