Toggle IBS op and fetch through /dev/cpuctl0 with hwpmc loaded and
check that every NMI hwpmc declined was claimed. Without the fix both
cases fail on an EPYC 9654.
Reviewed by: kib
MFC after: 2 weeks
Sponsored by: AMD
Signed-off-by: Osvaldo Janeri Filho <[email protected]>
Differential Revision: https://reviews.freebsd.org/D60766
178d0b5b8d adapted the Zen 5 pattern matching from Linux perf.
However, Linux prints CPU models with a single digit when under 0xF
(allowing |[[:xdigit:]] to match 0h-Fh), whereas hwpmc/libpmc formats
model numbers with two leading hex digits (00h-0Fh).
Fix the pattern to explicitly cover two-digit hex models in the 00h-0Fh
range, and add a test case verifying table selection across Zen 5 and Zen 6
cpuid strings.
Reviewed by: Ali Mashtizadeh <[email protected]>
Signed-off-by: Osvaldo Janeri Filho <[email protected]>
Fixes: 178d0b5b8d ("libpmc: Import AMD Zen 6 PMU events.")
Sponsored by: Advanced Micro Devices, Inc.
Differential Revision: https://reviews.freebsd.org/D60625
Processing an incoming ICMPv6 we need to find just the matching inpcb and
call udp_notify() on it.
The call to in6_pcbnotify() at the first glance seems like a notifying
sweep across the entire database, but it is not. It finds just the
matching inpcb, but does that in the most inefficient way! The added test
case proves that ICMPv6 processing stays the same before and after the
change. This weird use of in6_pcbnotify() can be tracked down all the way
to the initial KAME code.
Reviewed by: tuexen, gallatin
Differential Revision: https://reviews.freebsd.org/D60967
fdcopy() skips plain kqueues and close-on-fork descriptors when it
copies the table into the child. Check that dup(2) in the child still
returns the lowest unused descriptor, both when the skipped descriptor
is the lowest free slot and when it sits above an existing hole.
Test cases:
kqueue_no_hole a plain kqueue is the lowest descriptor; the
child's dup() reuses its slot
kqueue_two two adjacent plain kqueues; the child's dup()
returns the lower one
kqueue_above_hole a plain kqueue sits above a closed descriptor;
the child's dup() returns the hole
kqueue_cponfork a KQUEUE_CPONFORK kqueue is copied; the child's
dup() returns the next slot
clofork_no_hole an O_CLOFORK descriptor is the lowest one; the
child's dup() reuses its slot
clofork_above_hole an O_CLOFORK descriptor sits above a closed
descriptor; the child's dup() returns the hole
Without 99a58803f9, kqueue_no_hole, kqueue_two and
clofork_above_hole fail.
PR: 300234
Reviewed by: kib
MFC after: 1 week
MFC with: 99a58803f9
Co-authored-by: Claude Code Opus 5.5
Differential Revision: https://reviews.freebsd.org/D61124
Prior to this change, `jail_get` when called with `JAIL_USE|JAIL_GET_DESC`
would fail to return a valid descriptor in the positive case because the
`JAIL_USE_DESC` block jumped to `found_prison` before the descriptor was
allocated. This resulted in the returned jail descriptor always being -1,
despite the call being successful.
This change fixes the logic so `jfd_out` is properly initialized in the
aforementioned scenario.
MFC after: 3 days
Reviewed by: jamie, ngie, adrian
Differential Revision: https://reviews.freebsd.org/D60984
sosend_generic() read the TLS record type past a TLS_SET_RECORD_TYPE
control message holding only a cmsghdr, and sent that stale byte.
Approved by: markj
Fixes: b2e60773c6 ("Add kernel-side support for in-kernel TLS.")
Sponsored by: Netflix
`ISO_RRIP_ANALYZE` is constructed in four places. Two of the
initializers set the `outlen` field while the other two,
`cd9660_rrip_analyze` and `cd9660_rrip_offset`, leave it uninitialized.
The uninitialized paths can dereference an invalid pointer on error
paths which causes a kernel panic.
To fix, I zero out `ISO_RRIP_ANALYZE` in all four places where it's
initialized and check that `outlen` is non-null on the error path
in `cd9660_rrip_loop`.
While testing the above, I encountered another kernel panic due to
mounting continuing after the error branch. Evidently, the ISO continued
mounting through the normal ISO 9660 path then triggered a panic down
the line due to a very broken file system from the ISO. To fix that, I
propagate the error from the RR path then fail in the mount path.
A previous iteration of this commit included the ISO from the PR. The
current iteration creates an ISO with makefs then corrupts it with a
small helper written in C that is a condensed version of the CD 9660
code. It checks the input ISO for a a Rock Ridge extension reference
then corrupts the length byte. This triggers the early failure in
cd9660_rrip_offset.
PR: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296853
Signed-off-by: Josh Megnauth <[email protected]>
Reviewed-by: ngie
Pull-Request: https://github.com/freebsd/freebsd-src/pull/2462
Reject empty keys in metadata lookups with EINVAL to prevent an infinite
loop while holding allprison_lock and pr_mtx. Add tests for empty-key
reads and writes with empty and populated meta/env buffers, trailing
newlines, and empty final values.
Reviewed by: igoro, jamie
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D61025
ip6_tryforward() sends time exceeded for an expiring packet before the
inbound pfil hooks have seen it, whereas ip_tryforward() and
ip6_forward(), which ip6_input() calls after the hooks, check it
afterwards. On the fast path the router therefore answers packets the
firewall blocks inbound, and pf never handles the expiry itself: a
nat64 (af-to) packet with hop limit 1 gets a time exceeded error from
the router, which a "block" ruleset then drops on the way out, instead
of the one pf_translate_af() sends with the untranslated addresses.
Check the hop limit after the inbound hooks.
Reviewed by: kp
Fixes: 5a1842a2 ("Add ip6_tryforward() - a run to completion ...")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D61034
ip6_forward() has run the outbound hooks with pfil_mbuf_fwd() since
b52b61c0b6, and ip_tryforward() since 1f4c3887e3, but
ip6_tryforward() still calls pfil_mbuf_out(). pf therefore handles a
packet on the IPv6 fast path as locally generated: it skips the
packet-too-big error it sends with the untranslated addresses, and
pf_refragment6() sends reassembled packets out through ip6_output()
instead of ip6_forward(), so their fragments leave with the hop limit
not decremented.
Use pfil_mbuf_fwd() in ip6_tryforward() as well. The new
fragmentation_pass:v6_refrag_hlim test sends a packet that pf
reassembles and refragments through the fast path, and checks that its
fragments leave with the hop limit decremented once; before this change
they leave with it unchanged.
Reviewed by: kp
Fixes: b52b61c0 ("pf: distinguish forwarding and output cases for ...")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D61033
If two pfsync hosts have different timeout values set it's possible for
an underflow to occor when importing a state. If the destination host
has a shorter timeout set than the exporting host it's possible for the
state to be older than the importing host's timeout value, which results
in an underflow and a state with an unreasonable expiry time.
Check for this, and avoid the underflow. While here also account for the
timeout being longer than our uptime.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60950
Open /dev/pf and a generic Netlink socket as root, drop to nobody and
exec pfctl with both inherited, the way authpf(8) runs it. Without -l
the load is refused with EPERM; with it the rules land in the anchor.
An unusable descriptor is an error, not a fallback to a new socket.
Skips when fdescfs is not mounted, which -p /dev/fd/N needs.
PR: 291981
Signed-off-by: Avinash Duduskar <[email protected]>
Reviewed by: kp
Pull Request: https://github.com/freebsd/freebsd-src/pull/2508
The new `googletest` kyua test interface--added in 0.15.0 and fixed in
0.15.1--allows tests to be executed and handled in a more fine-grained
manner than the way it was prior to this commit.
This change deletes the `capsicum-test` ATF wrapper script,
`functional.sh`, and all supporting logic in `googletest.test.mk` as
well as this change makes that logic unnecessary.
MFC after: 1 month
MFC with: b68969979d ("contrib/kyua: update to 0.15.1")
RSS hash types are encoded values, not independent flags. The bitmask
check in M_HASHTYPE_ISHASH_TCP() also accepts UDP, address-only and opaque
hash types, causing the syncache to retain them instead of falling back
to a software TCP hash.
Compare against the three TCP four-tuple hash types after masking the
inner-header flag. Keep the existing macro interface and use an inline
helper to preserve single evaluation of its argument.
Add ATF coverage for all 256 hash-type byte values, including inner-header
hashes, and verify single evaluation of the mbuf argument.
Reviewed by: cc, gallatin
Fixes: a485399f88 ("tcp: restrict flowtype copying to specific RSS TCP types")
Sponsored by: BBOX.io
pf_state_key_attach() attaches the wire key first and then the stack
key, setting sks to NULL before the second pass. When the stack key
collides with an existing state, the error path removes the wire key
again but then frees sks, which is NULL by then: the stack key leaks.
pfsync hits this. A peer that gets a plain state in a bulk update
before a redirected state whose stack key is the plain state's key
fails to import the redirected state, leaks its stack key, and leaks
another one with every later update of that state.
Free sk, the key of the pass that collided (skw on the wire pass), and
add a test.
Reviewed by: kp
Fixes: 371bd29d4b ("pf: fix potential state key leak")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60951
"LDFLAGS= -lutil" dropped LDFLAGS from make.conf for every test in the
directory.
Approved by: glebius
Fixes: c3ac06161d ("nmount: Introduce the "check_fsid" option")
Sponsored by: Netflix
This fixes the flaky testcase in CI[0].
While here:
* fix a typo in a comment
* remove an unnecessary import
* fix this deprecation warning:
/usr/local/lib/python3.12/site-packages/scapy/contrib/igmp.py:12:
DeprecationWarning: scapy.contrib.igmp is deprecated. Please use
scapy.layers.igmp instead !
[0] https://ci.freebsd.org/job/FreeBSD-main-amd64-test/29813/testReport/junit/sys.netpfil.pf.igmp/py/TestIGMP__test_ip_opts/
Reviewed by: kp
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
While here, remove two munmap(2) calls on mappings the tests require to
have failed, since they are practically dead.
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60800
libpfctl sends a table definition in chunks of 256 addresses, each as
its own PFNL_CMD_INA_DEFINE. The kernel treated every chunk as a new
definition and replaced the shadow table, so only the last chunk
survived.
Mark the chunks after the first with PF_ID_APPEND and have the kernel
add them to the shadow table in progress. A request without the
attribute still replaces the shadow; one with it and no definition in
progress fails with EINVAL. Old kernels ignore the attribute, so both
halves are needed; the ioctl sends all addresses at once and is not
affected. Mask the flags userland passes to PFR_FLAG_ALLMASK, as
PFR_FLAG_APPEND is kernel-internal.
Add a test that defines a table of 1,000 addresses, also in an anchor.
Reviewed by: kp
Fixes: 219ce30638 ("pf: convert DIOCRINADEFINE to netlink")
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60876
pfr_remove_kentry() returns without removing an entry whose mark is
set. The mark is scratch space for the operations that handle a list
of addresses: each resets it before use and leaves it set on the
entries it kept, so after "pfctl -T replace" or "pfctl -T zero" of an
address the entry stays marked. An address a source limiter put in
its table is then never taken out again when the source falls below
the low-water mark.
Remove the entry whether it is marked or not; nothing else is in the
work queue.
Add a regression test.
Reviewed by: kp
Fixes: 4616481212 ("pf: introduce source and state limiters")
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60530
This is the program that found the races fixed in 1f1043d550. One
thread keeps a pattern in f14-f31 across a signal, while helpers pinned
to the same CPU keep different patterns in the real registers and get
woken up from another CPU to preempt it at random points. If the kernel
ever hands it somebody else's registers, the pattern doesn't match.
The register loads, the thr_kill() and the handshake with the helper are
in assembly so that nothing touches the FP registers between sigreturn
and the check. It runs for ten seconds and is skipped with fewer than
two CPUs.
Requested by: adrian
Approved by: jhibbits
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D60411
* ggatel: fix piped output. Flush stdout before daemonizing, so the
output can be read when it's in a command pipeline.
* ggated: bind the port _before_ daemonizing, so an invoking script can
be sure that the port is bound as soon as the command returns.
* tests: allow ggatec or ggatel to automatically allocate a device
number instead of choosing one in a racy way.
With all of these changes I can no run the tests 1000 times without
fail. And in parallel, too.
MFC after: 1 week
Sponsored by: ConnectWise
PR: 298942
Reported by: siva
Reviewed by: ngie
Differential Revision: https://reviews.freebsd.org/D60707
sndbuf_resize() and sndbuf_remalloc() drop the channel lock in order to
allocate the new buffer(s) with M_WAITOK. Before doing that they verify
that the buffer is not mapped, but this could change while the lock is
dropped, as there is no higher-level synchronization which prevents
buffer resize (e.g., via the SNDCTL_DSP_SETBLKSIZE ioctl) from happening
concurrently with mmap. Thus, these checks are insufficient.
Modify sndbuf_resize() and sndbuf_remalloc() to revalidate after
reacquiring the lock. Extend them to check for a couple of channel
flags, mirroring the check in chn_resizebuf(). Modify chn_resizebuf()
to revalidate state after reacquiring the channel lock.
We could also allocate new buffers with M_NOWAIT and so avoid dropping
the lock. Then, I think we could go even further and invoke
CHANNEL_SETBLOCKSIZE and CHANNEL_SETFRAGMENTS with the channel lock
held. But really it would be better to ensure that dsp operations are
serialized; there is no reason for mmap and chn_resizebuf() to be able
to run in parallel, we should not be relying on the channel lock for
this. So, let's keep a more minimal approach here.
Add a simple regression test.
Approved by: so
Security: FreeBSD-SA-26:71.sound
Security: CVE-2026-101308
Reviewed by: christos
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60554
Cover the interface identifier selection in in6_ifadd(): a /64
link-local address provides the identifier, while a /128 link-local
address or no link-local address at all yields the EUI-64 identifier
derived from the MAC address. Each case asserts the exact
autoconfigured address. ndp_prefix_len_mismatch reaches the same
fallback with a /127 link-local address, but only checks that some
address was configured.
Stable addresses (RFC 7217) are the default and bypass both paths, so
the host disables them. The advertisement goes to all nodes, and an
interface only joins that group with its first address, so the case
without a link-local address gives the host a static address from
another prefix.
ra.py now takes the Ethernet source address from --sendif rather than
from a route lookup; for ff02::1 that lookup fails in scapy 2.7.0.
Reviewed by: pouria
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60520
pf_hash_pool() hashes the first address of a pool as a whole struct
pf_addr_wrap, including the union that holds the kernel's pfi_dynaddr
or pfr_ktable pointer.
An interface pool such as "-> ($ext_if)" gets a new pfi_dynaddr on
every load, so with "set keepcounters" the rule never matches its
predecessor and loses its counters on every reload. The pointers also
differ between hosts: once a filter rule in the main ruleset has an
interface or table pool, pfsync peers disagree on the ruleset checksum
and bind every synced state to the default rule.
Hash the address with that union cleared. The rest of the address,
including the prefix length of an interface address, is hashed as
before, and the hash of a rule with a plain address pool does not
change.
Reviewed by: kp
Fixes: c6bcf6e6fd ("pf: include all elements when hashing rules")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60370
When an ICMPv6 query or reply matches a translated state,
pf_test_state_icmp() copies the state's virtual id into icmp6_id. Only
echo messages have an identifier there. For all other types the
virtual id is 0 and those two bytes hold something else; in a neighbour
advertisement they hold the R, S and O flags. The checksum was not
updated either, so icmp6_input() dropped the advertisement as a bad
checksum.
Unicast NUD probes to a link-local neighbour, such as the default
router, are sent from the link-local address. With a nat rule that
matches it (e.g. "from any"), every advertisement answering a probe was
dropped: NUD failed, the neighbour cache entry was deleted, and traffic
to the neighbour stalled until it was resolved again.
Only rewrite the id of echo messages, as the ICMPv6 error path already
does, and update the checksum, as the IPv4 path does.
Add a regression test.
Reviewed by: kp
Fixes: f1ddd7f1da ("pf: add forgotten fixup for icmp6 id's when translating")
See also: https://redmine.pfsense.org/issues/16236
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60542
Ensure we stop evaluating nat rules if we find a match in a nat-anchor.
PR: 299320
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
ndp_prefix_len_mismatch exercises the fallback in in6_ifadd() for an
interface whose link-local address does not have the advertised prefix
length (9e792f7ef7). Since a2eb0894b7 made stable addresses
(RFC 7217) the default, in6_ifadd() takes the interface identifier from
in6_get_stableifid() and never looks at the link-local address, so the
case passes without reaching the fallback. Turn stable addresses off
on the interface.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Check that once fsync(2), fdatasync(2), or a write(2) with O_SYNC or
O_DSYNC returns, the new data, the file size and every block pointer
leading to the data are on disk. The cases append a block, fill a hole,
append the first block that needs an indirect block and append below an
existing indirect block. Two more append after another write left a
new direct block unsynced, which with soft updates cuts the size and the
later pointers of an inode written meanwhile. With O_SYNC and O_DSYNC
on soft updates, those also check that the open already made the
unsynced block durable.
Each case runs on UFS without soft updates, with soft updates and with
SU+J.
The file systems live on md(4) and the checks read the inode, the
indirect block and the data block straight from the device with libufs
right after the synchronous call returns. There is no cache in front
of the disk device, so this shows what would survive a crash at that
moment without having to crash anything.
Sponsored by: Sippy Software, Inc.
Reviewed by: pho
Tested by: pho
Differential Revision: https://reviews.freebsd.org/D60134
MFC after: 1 month
pf_source_used() puts a source in the table of its source limiter when
the source has more states than the high-water mark, and
pf_source_rele() takes it out again below the low-water mark. Both
changed the table in place: pf_source_used() from pf_create_state(),
with the rules lock held for reading, and pf_source_rele() from
pf_remove_state(), with no rules lock at all. A table may only be
changed with the rules lock held for writing, as packets look addresses
up in its radix tree at the same time. With INVARIANTS the first
insertion panics ("Lock pf rulesets not exclusively locked" in
pfr_route_kentry()); without, the tree can be corrupted.
Queue the changes instead, as pf_overload_task() does for overload
tables, and make them from a task with the rules lock held for writing.
An entry names the limiter by its id and remembers its table: the
limiter, or its table, may be gone or replaced by the time the task
runs, and then the entry is dropped. pfsr_intable changes only once
the change is queued, so a failed allocation is retried the next time
the source crosses a mark; a removal is also retried when the source is
purged. Drain the task when a vnet goes away, after its last state.
Add a regression test.
Reviewed by: kp
Fixes: 4616481212 ("pf: introduce source and state limiters")
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60526
When a message outgrows the writer's buffer, _nlmsg_refill_buffer()
allocates a larger one and moves the unfinished message there. The new
buffer was sized for the data about to be added alone, so with enough of
the message already written the caller wrote past its end and left it
with datalen > buflen. A 20-byte message plus an attribute of 8176
bytes got a buffer of 8192 bytes for 8200 bytes of data, and reading it
panicked an INVARIANTS kernel in nl_soreceive().
Size the new buffer for both, and add a ktest for it.
Reviewed by: glebius
Fixes: 7e5bf68495 ("netlink: add netlink support")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60541
In principle, inotify can be used to leak timing information about I/O
device accesses by privileged process, which might be sensitive, e.g.,
in the case of /dev/input. See https://inoti.fyi/#1-linux-inter-keystroke-timing
In practice this does not work since I/O to devfs nodes does not go
through vnodes, so the INOTIFY() calls in various VOP hooks do not fire.
But, let's explicitly define a no-op VOP_INOTIFY to help ensure that no
one tries to "fix" this bug.
Alternately we could simply ignore VCHR/VBLK vnodes in vn_inotify().
However, maybe someday it'll be desirable to enable inotify for specific
device files, in which case the filtering should live in devfs.
Add a regression test.
Reported by: Sudheendra Raghav Neela <[email protected]>
Reviewed by: kib
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60364
The test pinged an unanswered address and then deleted the resulting
INCOMPLETE neighbor entry.
The kernel frees that entry after about 3s, so on a loaded VM,
ndp -d could run too late and fail with ENOENT.
Configure 2001:db8::2 on epair0b so the ping gets a reply and the
entry becomes REACHABLE.
Approved by: pouria
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D60348
linux and linux64 are file names, not module names. The corresponding
module names are linuxelf and linux64elf, respectively, so these tests
were always being skipped.
Fixes: b98d169d1f ("tests/sys/vfs: add ABI-root absolute symlink tests")
Sponsored by: The FreeBSD Foundation
The PFNL_CMD_TABLE_TEST_ADDRS reply carries only the match count, so
the per-address feedback from pfr_tst_addrs() is lost:
"pfctl -v -T test" lists nothing and "pfctl -vv -T test" reports
every address as "nomatch".
Return each address, as updated by pfr_tst_addrs(), in a nested
PF_TAS_ADDR attribute, and decode them into the caller's array in
libpfctl. PF_TA_ADDR is not reused: it shares its value with
PF_TAS_ASTATS, which older libpfctl would decode into an
uninitialised target. That target was also read when no reply was
parsed, so the match count could be garbage; initialise it.
Add a regression test.
Reviewed by: kp
Approved by: kp (mentor)
Fixes: 281282e935 ("pf: convert DIOCRTSTADDRS to netlink")
See also: https://redmine.pfsense.org/issues/17135
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60146
The chunked table address functions (set, add, del, clr_astats) add
each chunk's result to the caller's counter without initialising it.
pfctl reuses nadd for the number of tables created, so a replace that
also creates the table is off by one:
pfctl -t foo -T replace 192.0.2.1
reports "2 addresses added".
Zero the counters first, as pfctl_test_addrs() already does. Remove
the workaround for the add case from pfctl (da64f6e047), which is
no longer needed.
Add a regression test.
Reviewed by: kp
Approved by: kp (mentor)
Fixes: 08ed87a4a2 ("pf: convert DIOCRSETADDRS to netlink")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60174
geom_subr.sh serves both legacy TAP tests and ATF tests. It defaults to the
TAP path, so ATF tests must set ATF_TEST=true before sourcing it.
Sponsored by: Netflix
The netlink encoding of struct pfr_addr omits pfra_fback, so no
per-address feedback reaches userspace. In particular,
pfr_get_astats() marks entries of tables without counters with
PFR_FB_NOCOUNT, which pfctl uses to skip their counters, so
"pfctl -v -T show" prints zero counters for such tables.
Add PFR_A_FBACK, emit it from the kernel and decode it in libpfctl.
Add a regression test.
Reviewed by: kp
Approved by: kp (mentor)
Fixes: 08f54dfca1 ("pf: convert DIOCRGETASTATS to netlink")
Sponsored by: Rubicon Communications, LLC ("Netgate")
When an fdescfs mount has the nodup option set, fdesc_lookup(/dev/fd/n)
returns the vnode referenced by file descriptor n, rather than returning
an fdescfs vnode. This meant that fd metadata attached to fd n was not
preserved when reopening the file, which is contrary to the expected
semantics for capsicum rights and the UF_RESOLVE_BENEATH fd flag. For
regular fdescfs mounts, this metadata is copied via dupfdopen().
Fix the problem by passing up this metadata through the nameidata
structure. Thus, if one opens /dev/fd/n, the returned fd will inherit
UF_RESOLVE_BENEATH and the capability rights of fd n. Add some
regression tests as well.
Approved by: so
Security: FreeBSD-SA-26:66.jail
Security: CVE-2026-101304
Reported by: Jan Bramkamp
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59886
pfr_clr_astats() looks up each address it is given and inserts the entry
it finds at the head of a work queue. If the same address is given more
than once, the entry is inserted twice and the second insertion makes it
its own successor. pfr_clstats_kentries() then walks the queue forever,
with the rules lock held for writing, so packet processing and every
other pf operation in that vnet stop as well. To reproduce:
pfctl -e
pfctl -t foo -T add 192.0.2.1
pfctl -t foo -T zero 192.0.2.1 192.0.2.1
Do as pfr_del_addrs() does: clear pfrke_mark on the entries named, then
queue an entry only the first time it is seen. An address given more
than once is cleared, and counted, once. Validate all addresses before
any entry is touched.
Add a regression test.
Reviewed by: kp
Approved by: kp (mentor)
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60103
Since DIOCRSETADDRS was converted to netlink, pf_handle_table_set_addrs()
calls pfr_set_addrs() with a NULL size2, as the netlink interface has no
buffer to return the deleted addresses in. pfr_set_addrs() only checked
size2 for NULL at the end of the function; with PFR_FLAG_FEEDBACK set it
dereferenced it unconditionally first. pfctl sets PFR_FLAG_FEEDBACK
when run with -v, so "pfctl -v -t foo -T replace ..." panicked the
kernel with a NULL pointer dereference. To reproduce:
pfctl -e
pfctl -t foo -T add 192.0.2.1
pfctl -v -t foo -T replace 192.0.2.2
Check size2 for NULL before dereferencing it, as is already done at the
end of the function. The per-address feedback for added and changed
addresses is still copied back as before; only the list of deleted
addresses, which the netlink caller has no room for, is skipped.
While here, compare size2 against NULL explicitly in the second check as
well, per style(9).
Add a regression test.
Approved by: kp (mentor)
Fixes: 08ed87a4a2 ("pf: convert DIOCRSETADDRS to netlink")
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D60096