The rfb code maintains an array of CRCs for 32x32 tiles in the
framebuffer. This array is sized statically based on the rfb code's
notion of the maximum framebuffer size, which changed in commit
fb51ddb20d without updating the rfb code.
Morever, writes to the framebuffer BAR can modify the recorded height
and width of the framebuffer. These values were not validated against
the maximum at all, unlike the parameters set via bhyve config.
Fix these problems:
- Define the maximum width and height in a shared header file so that
they do not get out of sync again.
- In pci_fbuf_render(), don't resize the console if the new dimensions
are too large.
- Add a mutex to synchronize framebuffer BAR I/O with the rfb thread.
Approved by: so
Security: FreeBSD-SA-26:72.bhyve
Security: CVE-2026-101311
Fixes: fb51ddb20d ("bhyve: increase fbuf display resolution limit")
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60680
The length of each block in the stream must be non-zero. This is
assumed in hda_transfer(), otherwise an out-of-bounds read or write is
possible.
Use atomic loads to access stream descriptor fields, since they are
guest-controlled. Make sure that the descriptor array is suitably
aligned so that we can drop the __packed annotation from the structure
definition; per section 3.3.42 of the HDA spec the BDL pointer is
supposed to be 128-byte aligned, in fact.
Approved by: so
Security: FreeBSD-SA-26:72.bhyve
Security: CVE-2026-101310
Reported by: Brian Delgado from Intel using Anthropic Opus 4.8
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60678
rts->erst_p and rts->erstba_p are pointers to guest-controlled memory
which describe the event rings and pending event array, respectively.
The device model was not validating the size nor saving the value.
As a result, the bounds checks in pci_xhci_insert_event() were
susceptible to TOCTOU races.
Fix pci_xhci_rtsregs_write() to save the ring size in a softc field.
Validate that the size isn't larger than the maximum allowed by the XHCI
specification (64KB, or 4096 TRBs).
When processing TRBs, make sure we don't load fields more than once.
Make sure that pci_xhci_trb_next() doesn't return a pointer to host
memory. When handling ERDP writes, make sure that the guest-supplied
address is actually a pointer into the TRB array, and ignore the write
if not.
Approved by: so
Security: FreeBSD-SA-26:72.bhyve
Security: CVE-2026-101309
Reported by: Brian Delgado from Intel using Anthropic Opus 4.8
Differential Revision: https://reviews.freebsd.org/D60677
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
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60554
Most implementations of CHANNEL_SETBLOCKSIZE and CHANNEL_SETFRAGMENTS
were not checking this. This is probably not a big problem: it's
unlikely for sndbuf_resize() to fail due to the refcount check in this
case since it's operating on the hardware buffer, which doesn't get
mmaped. But, I will add more reasons for it to fail in the next patch,
so let's be more careful.
This change modifies various CHANNEL_SETBLOCKSIZE implementations to
check for errors. In some cases I reordered things to avoid updating
driver state until after sndbuf_resize() succeeds.
Return 0 from CHANNEL_SETBLOCKSIZE to indicate an error, as it otherwise
returns the new block size. We could change the interface to return
both an error number and a block size, but that would break at least one
out-of-tree driver and I wish to avoid that here. Make sure that errors
from CHANNEL_SETFRAGMENTS are returned to userspace.
Approved by: so
Security: FreeBSD-SA-26:71.sound
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60553
The FD_RESOLVE_BENEATH flag is supposed to be sticky. It's set when you
receive an fd from a different jail and preserved by openat(<dfd>) etc..
However, if you send the fd to yourself, the flag is stripped since
SCM_RIGHTS message don't preserve file descriptor flags.
Fix this by preserving those flags and checking for UF_RESOLVE_BENEATH
in restrict_rights().
Approved by: so
Security: FreeBSD-SA-26:66.jail
Security: CVE-2026-101306
Fixes: 350ba9672a ("unix: Set O_RESOLVE_BENEATH on fds transferred between jails")
Reviewed by: kib
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58317
(cherry picked from commit 586e2b3d89)
(cherry picked from commit 441885dcff)
The FD_RESOLVE_BENEATH flag was intended to try to resolve bugzilla PR
262179 without entirely disallowing fd passing between jails. However,
one can use renameat() to bypass the restriction: upon receiving a
directory fd with FD_RESOLVE_BENEATH set, a jailed process can still
move its CWD or one of its ancestors to the directory, and just cd
out of its jail root.
So disallow renameat() when either the source or destination directory
fds has FD_RESOLVE_BENEATH set, like we do with fchdir() and fchroot()
to prevent similar escapes.
Approved by: so
Security: FreeBSD-SA-26:66.jail
Security: CVE-2026-101305
PR: 262179
Reported by: [email protected]
Reviewed by: olce, kib
Differential Revision: https://reviews.freebsd.org/D59875
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
These routines let one compute the intersection of two sets of filecaps
or capability rights, just as filecaps_merge() and cap_rights_merge()
compute the union. This will be useful in an upcoming patch.
filecaps_intersect() is complex due to the need to merge sets of ioctls.
For now this is implemented with a dumb nested loop on the basis that
ioctl lists are typically short enough that this is fine. It may be
better to instead sort the two lists first and step through them
together.
No functional change intended.
Approved by: so
Security: FreeBSD-SA-26:66.jail
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59885
In a couple of places we want to know whether someone has limited rights
on an fd. There, we want a predicate which determines whether the set
of rights is smaller than CAP_ALL, and whether there are explicit ioctl
or fcntl lists. Factor this out into a helper function, in preparation
for use elsewhere.
No functional change intended.
Approved by: so
Security: FreeBSD-SA-26:66.jail
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59884
When performing an unconnected sendto() on a v6 UDP socket in a classic
jail, we were not applying the usual policy of replacing the loopback
addr with the jail's primary IP. Compare with, e.g., udp6_connect() or
the IPv4 udp_send(). Fix that.
Approved by: so
Security: FreeBSD-SA-26:69.udp
Security: CVE-2026-101303
Reported by: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li,
and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by: bz, glebius
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59772
(cherry picked from commit fecb9537a8)
(cherry picked from commit 809221661a)
If the entire plaintext is zero-filled, the backwards walk in
tls13_find_record_type() would return the offset of the last byte of the
TLS header. This causes an underflow when decrypting, resulting in a
null pointer dereference.
Fix the bug and add a regression test.
Approved by: so
Security: FreeBSD-SA-26:67.ktls
Security: CVE-2026-101302
Reviewed by: gallatin, jhb
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59767
(cherry picked from commit 7c5e457d3a)
(cherry picked from commit fc1a02c93b)
semop() may sleep waiting for a semaphore. Upon waking up, it checks to
see if the set's sequence number has changed, indicating that the set
was removed. The sequence number is not wide enough to prevent a false
negative due to wraparound, in which case the subsequent access of
`semakptr->u.__sem_base[sopptr->sem_num]` may be out of bounds. This
race can be leveraged to elevate privileges.
Fix this by introducing a 64-bit sequence number for each semaphore
pool. This is wide enough to make the race impossible to hit. Allocate
a separate array for them, as we cannot really change the layout of
struct semid_kernel since some userspace tools (e.g., ipcrm(1)) embed
the layout.
While here, use semvalid() instead of open-coding its implementation,
convert a couple of flags to be bool, and use a better variable name to
store required permissions.
Approved by: so
Security: FreeBSD-SA-26:64.sysvsem
Security: CVE-2026-58098
Reported by: Reo Shiseki
Reported by: Andrew Griffiths
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59347
The check for whether shm_lp_psind was assigned was unlocked. This race
can be exploited to create an object with psind==2 but with only
pagesizes[1] worth of pages populated. This in turn can be used to
escalate privileges.
Fix this by acquiring the rangelock earlier. In shm_mmap_large(),
assert that we hold the rangelock. In shm_write(), annotate an unlocked
load of shm_lp_psind.
Approved by: so
Security: FreeBSD-SA-26:63.posixshm
Security: CVE-2026-58094
Reported by: tsune of GMO Cybersecurity by Ierae, Inc. working with TrendAI Zero Day Initiative
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59104
The TIOCSCTTY ioctl handler drops the tty lock in order to acquire the
proctree relock. After relocking the tty, it did not revalidate the
tty state, and it could end up linking a doomed tty to the calling
process' session. This race can be exploited to escalate privileges.
TIOCSPGRP has a similar race, fix that too.
Approved by: so
Security: FreeBSD-SA-26:62.tty
Security: CVE-2026-58093
Reported by: tsune of GMO Cybersecurity by Ierae, Inc. working with TrendAI Zero Day Initiative
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59126
Per RFC1717 section 5.1.3, the option length must be at least three.
Processing an undersized option would trigger a large out-of-bounds
write.
Approved by: so
Security: FreeBSD-SA-26:60.ppp
Security: CVE-2026-58096
PR: 271910
Reported by: Robert Morris
Reported by: Décio Brandão (0xDBJ)
Reviewed by: emaste
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58554
(cherry picked from commit b9d07a4308)
(cherry picked from commit 30b4bdd451)
Each byte of the address is represented by a pair of characters, so we
should be multiplying len by 2 when figuring out how much buffer space
we have. Previously, a sufficiently large option could cause an
overflow of the global "result" buffer.
Approved by: so
Security: FreeBSD-SA-26:60.ppp
Security: CVE-2026-58095
Reported by: Joshua Rogers <[email protected]>
Tested by: Décio Brandão (0xDBJ)
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58555
(cherry picked from commit e004ff15f8)
(cherry picked from commit 607c41d8f8)
This function has a loop where it attempts to lock all channels in a
group. If doing so would block, it releases all locks, sleeps for a
bit, and tries again. However, once the syncgroup lock is dropped,
nothing prevents the syncgroup structure from being freed.
Fix the inner loop: after waking up, break out of it unconditionally and
start everything again. I think the old code was also buggy and not
well-exercised: after waking up we'd continue to try and continue
locking channels. Then we'd try again from the beginning and fail to
lock the channels we had already locked.
Approved by: so
Security: FreeBSD-SA-26:58.sound
Security: CVE-2026-58091
Reported by: Hazley Samsudin of GovTech CSG
Reviewed by: christos
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58912
When a process execve()s, pmc_process_exec() is supposed to evaluate
whether the new image is setuid/setgid and if so, whether to detach
PMCs. This was handled by pmc_can_attach(), which is effectively an
open-coded copy of cr_xids_subset().
Unfortunately, the test of the result of this function was inverted,
with the result that we'd detach PMCs only if the predicate said it was
okay to do so. It appears the bug has always been there; it seems the
intent was to return 0 on "success", i.e., it is okay to attach the
PMCs, much like p_candebug(). Commits 1c3c698ba4 and 1c40b15971
obscured this a bit.
I think this check is trying to be too clever. Let's make it simpler:
simply do not attach PMCs unless the owner is privileged. This is how,
e.g., ktrace works. I do not think it's worth trying to be more
sophisticated than this unless we can generalize the policy in a way
that's applicable to other subsystems.
Also fix a bug at the end of pmc_process_exec():
pmc_detach_one_process() will call pmc_remove_process_descriptor() for
us.
Approved by: so
Security: FreeBSD-SA-26:56.hwpmc
Security: CVE-2026-58089
Reported by: netchild
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59102
The check for the extended signature table was backwards, so we always
ignored it.
We should verify that the extended signature table fits within the total
image size.
Approved by: so
Security: FreeBSD-EN-26:20.microcode
Reviewed by: jrm, kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D57209
(cherry picked from commit 0beb172898)
(cherry picked from commit 38cbd2588f)
In an ELF coredump, each dumped vm_map_entry is represented by a
segment. __elfN(coredump) first computes the number of segments by
looping over the vm_map entries (in each_dumpable_segment()), then
allocates a buffer to hold the ELF header and program headers, then
loops over the entries again to populate the program headers.
each_dumpable_segment() holds the vm_map read lock, but that lock is
dropped between the two calls. If the map is shared with another
process, via rfork(), then the map can change. cb_put_phdr() did not
account for this, and so could write out of bounds.
Add a check to prevent this; simply do not write out excess segments.
Approved by: so
Security: FreeBSD-SA-26:55.elf
Security: CVE-2026-58088
Reported by: Maik Muench of Secfault Security
Reviewed by: kib, emaste
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58416
These commands take a snapshot of the size of a semaphore set, then drop
the lock and malloc an appropriately sized array before reacquiring the
lock. A comment explains why this is (probably) safe. Unfortunately,
it's wrong; it is indeed possible for a malicious userspace to create
and destroy 2^{15} sets in the window where the lock is dropped. This
race can lead to out-of-bounds reads and writes, and that can be
exploited to elevate privileges.
Replace the assertions with runtime checks.
Approved by: so
Security: FreeBSD-SA-26:54.sysvsem
Security: CVE-2026-58087
Reported by: Maik Muench of Secfault Security
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58421
In the ISO2022-CN encoding, characters may require at least seven bytes,
and MB_LEN_MAX==6 is insufficient. From code inspection,
_ISO2022_sputwchar() can emit 10 bytes in the worst case, so use that to
size buffers.
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:49.iconv
Security: CVE-2026-58082
Reviewed by: kevans
Differential Revision: https://reviews.freebsd.org/D57950
wcrtomb may store up to 2 2-byte escape sequences to the state buffer in
addition to the character itself. In the worst case, a 3-byte heap
overflow is possible.
Approved by: so
Security: FreeBSD-SA-26:49.iconv
Security: CVE-2026-58081
Reviewed by: kevans
Differential Revision: https://reviews.freebsd.org/D57949
sendfile(2) can transmit POSIX shared memory objects. Typically it will
look up and wire each page before sending it to a socket; once
transmission is complete, the page is unwired and typically released
back into the page queues. sendfile() has an advisory flag, SF_NOCACHE,
which means, "try to free the page once transmission is complete." This
is implemented in vm_page_release(), which expects to operate on managed
pages.
Pages belonging a largepage object are de-facto wired not explicitly so.
Thus, vm_page_release() will unwire and, having found no additional
references, free the page. Because mappings of largepage objects are
unmanaged, userspace can still access the now freed page.
Fix the problem by explicitly wiring largepage pages. Make the VM
object destructor responsible for unwiring and freeing them.
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:44.posixshm
Security: CVE-2026-49427
Reported by: Chris Jarrett-Davies <[email protected]>
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57832
We correctly handled ftruncate(), but not open(O_TRUNC).
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:44.posixshm
Security: CVE-2026-49428
Reported by: Chris Jarrett-Davies <[email protected]>
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57831
As with truncation, the operation isn't supported, but nothing prevented
it.
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:44.posixshm
Security: CVE-2026-49428
Reported by: Chris Jarrett-Davies <[email protected]>
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57830
Malicious userspace might switch TCP stacks twice while the inpcb lock
is dropped. If it does so, the validation of tp->t_fb might succeed,
but the saved pointer to the stack PCB might be invalid. Reload it to
avoid this problem, as BBR already does.
Approved by: so
Security: FreeBSD-SA-26:43.tcp
Security: CVE-2026-49422
Reported by: Maik Münch
Reviewed by: tuexen
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57791
The unlinkat(2) and funlinkat(2) system calls were ignoring
AT_RESOLVE_BENEATH.
Also pass pathseg through instead of assuming it's UIO_USERSPACE.
Add some tests which make sure that AT_RESOLVE_BENEATH is handled
properly by various system calls.
Approved by: so
Security: FreeBSD-SA-26:42.unlinkat
Security: CVE-2026-49421
Reported by: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57790
Approved by: so
Security: FreeBSD-SA-26:41.libalias
Security: CVE-2026-49420
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57747
This commit squashes the following upstream commits:
#1860463a0ff6cd nvpair: Check for un-terminated strings in packed nvlist
#1861738cd6adcb Extend dataset zfs_ioc_set_prop() secpolicy
#18615738791027 Fix the integer type in zfs_ioc_userspace_many()
#1862306d8cfedb Add additional verification of size fields and strings
Approved by: so
Security: FreeBSD-SA-26:40.zfs
Security: CVE-2026-49429
Security: CVE-2026-49430
Security: CVE-2026-49431
Unmanaged device pager objects maintain a linked list of pages that were
returned from the fault handler. Initially, such pages are valid, but
msync(MS_INVALIDATE) can mark them invalid (and clean). They are not
removed from page tables (since they are unmanaged), but a subsequent
mlock() call can trigger a page fault that is handled by the pager.
dev_pager_getpages() then re-inserts the page into the linked list even
though it's already present there.
This patch fixes the problem by removing the linked list. OBJ_PG_DTOR
is set, so vm_object_terminate_pages() does nothing, and
dev_pager_dealloc() instead handles cleanup of the object.
Add a regression test case which triggers a queue.h assertion failure in
unpatched kernels.
Note, in stable branches we should avoid changing the layout of struct
vm_object.
Approved by: so
Security: FreeBSD-SA-26:37.vm
Security: CVE-2026-49418
Reported by: slidybat
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57743
Otherwise an unprivileged user can disable randomization of the base
address for PIEs even if they are setugid.
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:32.elf
Security: CVE-2026-49414
Reported by: David Berard
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57397
The runtime linker in glibc relies on the AT_SECURE auxv entry to know
whether the executable is set-ugid, if so then various dangerous
functionality such as LD_PRELOAD is disabled.
The check added in commit 669414e4fb failed to take into account the
fact that during execve, P_SUGID may not yet be set for a set-ugid
process. Correct the test.
Approved by: so
Security: FreeBSD-SA-26:30.linux
Security: CVE-2026-49413
Reported by: Minseong Kim
Fixes: 669414e4fb ("Implement AT_SECURE properly.")
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57350
We drop the inpcb lock in order to copy in the source list, but this
leaves a window where the multicast filter structure might be freed.
This can be exploited to obtain root privileges.
In the v4 code this race is mitigated by holding the global multicast
lock across the gap.
Restructure the code to copy in filters before doing anything else, so
that there's no need to drop the inpcb lock and reason about the
correctness of doing so. Do the same in the v4 code for consistency.
Approved by: so
Security: FreeBSD-SA-26:29.ip6_multicast
Security: CVE-2026-49412
Reported by: Andrew Griffiths <[email protected]>
Reported by: Maik Münch <[email protected]>
Reviewed by: glebius
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57347
The channel buffer mapped by dsp_mmap_single() may be freed when the
device handle is closed, but the mapping persists beyond that, allowing
userspace to read or write memory owned by a different consumer.
Fix the problem by adding a reference counter to the sound buffer.
Define pager ops for the VM object returned by dsp_mmap_single() and use
them to manage the extra reference.
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:27.sound
Security: CVE-2026-49417
Reported by: Lexpl0it, 75Acol, Liyw979, Rob1n
Reviewed by kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57393
Approved by: so
Security: FreeBSD-SA-26:25.thr
Security: CVE-2026-45256
Reported by: Igor Gabriel Sousa e Souza
Reported by: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by: emaste, kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57237
The f_menu_wpa_scan_results() function returns a list of networks
discovered by a scan. The untrusted network names are evaluated in
f_dialog_menu_wireless_edit. The quoting applied in
f_menu_wpa_scan_results() protects against evaluation of something like
"$(whoami)" but one can add single quotes to defeat that.
Pass the SSID names through f_shell_escape to work around this. Escape
single quotes in f_dialog_wireless_edit() and f_menu_wireless_configs()
too for consistency.
I note that this module doesn't seem to actually work, see e.g.,
bugzilla PR 229883.
Approved by: so
Security: FreeBSD-SA-26:23.bsdinstall
Security: CVE-2026-45255
Reported by: Austin Ralls
Reviewed by: dteske, des
Differential Revision: https://reviews.freebsd.org/D56974
- Fix an off-by-one in the system call number check. A value of
SYS_MAXSYSCALL was permitted.
- Validate the system call number after we've dealt with
syscall(2)/__syscall(2), since they pass the syscall number as an
argument.
- When the syscall number is for syscall(2) or __syscall(2), we must
make sure that nargs > 0 to avoid an underflow when shifting arguments
down.
Add regression tests.
Approved by: so
Security: FreeBSD-SA-26:21.ptrace
Security: CVE-2026-45253
Fixes: 140ceb5d95 ("ptrace(2): add PT_SC_REMOTE remote syscall request")
Reported by: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by: kib, emaste
Differential Revision: https://reviews.freebsd.org/D56978
Otherwise they are left on a freed list after procdesc_free() is called.
This can be exploited to elevate privileges.
Remove the PDF_SELECTED micro-optimization. doselwakeup() is a no-op if
no one ever called selrecord() on the file description, so I see no
reason to complicate the code to avoid the call.
Add some regression tests.
Approved by: so
Security: FreeBSD-SA-26:19.file
Security: CVE-2026-45251
Reported by: 75Acol, Lexpl0it, fcgboy, and robinzeng2015
Reviewed by: kib, oshogbo
Fixes: cfb5f76865 ("Add experimental support for process descriptors")
Differential Revision: https://reviews.freebsd.org/D56887
When the number of DHCP options exceeds a threshold, script_set_env()
will reallocate the environment, stored as an array of pointers. The
calculation of the array size failed to multiply by the pointer size,
resulting in a smaller than expected buffer which admits out-of-bounds
writes.
Approved by: so
Security: FreeBSD-SA-26:15.dhclient
Security: CVE-2026-42511
Reported by: Joshua Rogers of AISLE Research Team (https://aisle.com/)
Some options are written directly to the lease file, which may be parsed
by subsequent dhclient invocations. We must make sure that a malicious
server can't control the "medium" field of a lease definition, otherwise
they can achieve RCE by injecting one into the lease file, whereupon it
will be passed to dhclient-script, which passes it through eval.
Approved by: so
Security: FreeBSD-SA-26:12.dhclient
Security: CVE-2026-42511
Reported by: Joshua Rogers of AISLE Research Team (https://aisle.com/)
The buggy version allowed userspace to overflow the copy into adjacent
execve KVA regions, which enables, among other things, injecting
environment variables into privileged processes.
Approved by: so
Security: FreeBSD-SA-26:13.exec
Security: CVE-2026-7270
Reported by: Ryan Austin of Calif.io
Reviewed by: brooks, kib
Fixes: f373437a01 ("Add helper functions to copy strings into struct image_args.")
Differential Revision: https://reviews.freebsd.org/D56665
pmap_pkru_update_range() did not handle the case where a PDPE has PG_PS
set. More generally, the SET_PKRU and CLEAR_PKRU sysarch
implementations did not check whether the request covers a "boundary" vm
map entry. Fix this, add the missing PG_PS test, and add some tests.
Approved by: so
Security: FreeBSD-SA-26:11.amd64
Security: CVE-2026-6386
Reported by: Nicholas Carlini <[email protected]>
Reviewed by: kib, alc
Differential Revision: https://reviews.freebsd.org/D56184
The TIOCNOTTY handler detaches the calling process from its controlling
terminal. It clears the link from the session to the tty, but not the
pointers from the tty to the session and process group. This means that
sess_release() doesn't call tty_rel_sess(), and that pgdelete() doesn't
call tty_rel_pgrp(), so the pointers are left dangling.
Fix this by clearing pointers in tty_drop_ctty(). Add a standalone
regression test.
Approved by: so
Security: FreeBSD-SA-26:10.tty
Security: CVE-2026-5398
Reported by: Nicholas Carlini <[email protected]>
Reviewed by: kib, kevans
Fixes: 1b50b999f9 ("tty: implement TIOCNOTTY")
Differential Revision: https://reviews.freebsd.org/D56046
- When allocating a page, we should only consider the PG_ZERO flag when
handling the top-level page.
- Unconditionally reset the flag when restarting the fault handler.
Previously, vm_fault_busy_sleep() would fail to reset it.
Approved by: so
Security: FreeBSD-EN-26:05.vm
PR: 294039
Reviewed by: kib
Tested by: Peter Much <[email protected]>
MFC after: 3 days
Fixes: cff67bc43d ("vm_fault: only rely on PG_ZERO when the page was newly allocated")
Differential Revision: https://reviews.freebsd.org/D56234
(cherry picked from commit 04132e0100)
(cherry picked from commit 9b7c0f4f81)
svc_rpc_gss_validate() copies the input message into a stack buffer
without ensuring that the buffer is large enough. Sure enough,
oa_length may be up to 400 bytes, much larger than the provided space.
This enables an unauthenticated user to trigger an overflow and obtain
remote code execution.
Add a runtime check which verifies that the copy won't overflow.
Approved by: so
Security: FreeBSD-SA-26:08.rpcsec_gss
Security: CVE-2026-4747
Reported by: Nicholas Carlini <[email protected]>
Reviewed by: rmacklem
Fixes: a9148abd9d
nullfs_unlink_lowervp() is called with the lower vnode locked, so the
nullfs vnode is locked too. The following can occur:
1. the vunref() call decrements the usecount 2->1,
2. a different thread calls vrele() on the vnode, decrements the
usecount 0->1, then blocks on the vnode lock,
3. the first thread tests vp->v_usecount == 0 and observes that it is
true,
4. the first thread incorrectly unlocks the lower vnode.
Fix this by testing VN_IS_DOOMED directly. Since
nullfs_unlink_lowervp() holds the vnode lock, the value of the
VIRF_DOOMED flag is stable.
Thanks to leres@ for patiently helping to track this down.
PR: 288345
MFC after: 1 week
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D55446
(cherry picked from commit 8b64d46fab)
(cherry picked from commit 6ed3732276)
Approved by: re (cperciva)
Reported by: kib, kp
Fixes: 350ba9672a ("unix: Set O_RESOLVE_BENEATH on fds transferred between jails")
(cherry picked from commit 3ef39f58e5)
(cherry picked from commit 302120bcb9)
When one uses SIOCAIFADDR_IN6 to add a v6 address, it's possible to set
the preferred and valid lifetimes of the address. If the address
already exists, this ioctl will recalculate and update the expiry times
based on the provided timestamps.
When adding a new address, the lifetimes are inherited by the prefix as
well, but only if we create a new prefix. If the prefix already exists,
as it will in the case where an address is being updated rather than
being added, we do not touch the prefix lifetimes at all. This means
that the original address lifetime still applies to the route associated
with that prefix, so when the prefix expires, the route goes away.
This behaviour doesn't make a lot of sense: if the admin updates an
address lifetime, we should ensure that the prefix lifetime is updated
too. Make that change, ensuring that we do not shorten the prefix
lifetime, as the prefix might be shared among multiple interface
addresses.
Add a regression test.
Co-authored by: Franco Fichtner <[email protected]>
Reviewed by: pouria, zlei, ae
MFC after: 2 weeks
Sponsored by: OPNsense
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D54562
(cherry picked from commit 74999aac5e)
Tidy up a bunch of places that have the same duplicated logic. Simplify
callers of in6_init_prefix_ltimes(). No functional change intended.
Reviewed by: pouria, zlei, tuexen, glebius
MFC after: 2 weeks
Sponsored by: OPNsense
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D54561
(cherry picked from commit fb08f80eaf)
Each C file is compiled separately so these functions can't be inlined
except in the file where they are defined. Since these functions aren't
used outside smartpqi_request.c, just do the simple thing and make them
private to that file.
Reported by: gcc
Reviewed by: jrhall
Fixes: c558eca479 ("smartpqi: update to version 4660.0.2002")
Differential Revision: https://reviews.freebsd.org/D54732
(cherry picked from commit 75c591b267)
By default, when ifconfig shows a v6 address derived from a
router-advertised prefix, it shows the initial preferred and valid
lifetimes. When -L is specified, it is supposed to show the remaining
lifetimes, but this was broken in the conversion to netlink.
Fix that, and add a regression test which validates ifconfig output
before and after a short-lived address expires.
Reported by: Franco Fichtner <[email protected]>
Reviewed by: melifaro, allanjude, Seyed Pouria Mousavizadeh Tehrani
Fixes: 4c91a5dfe4 ("ifconfig: make interface and address listing use Netlink as transport")
MFC after: 2 weeks
Sponsored by: OPNsense
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D54294
(cherry picked from commit df6861d755)
If we get a random number, the NZCV is set to 0b0000. Then
"cset %w1, ne" will test whether Z == 0 and set %w1 to 1 if so.
More specifically, "cset %w1, ne" maps to "csinc %w1, wzr, wzr, eq",
which stores 0 in %w1 when NZCV == 0b0100 and 1 otherwise.
Thus, on a successful read we expect ret != 0, so the loop condition
needs to be fixed. In practice this means that we would end up trying
to fetch entropy up to ten times in a row. If all attempts are
successful, the last will be returned, otherwise no entropy will be
returned.
Reported by: Kevin Day <[email protected]>
Reviewed by: andrew
Fixes: 9eecef0521 ("Add an Armv8 rndr random number provider")
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D54259
(cherry picked from commit 9381188350)
pfsync_state_export() takes a pointer to a union that is in reality a
pointer to one of the three state formats (1301, 1400, 1500), and zeros
the union. The three formats do not have the same size, so zeroing is
wrong when the format isn't that which has the largest size.
Refactor a bit so that the zeroing happens at the layer where we know
which format we're dealing with.
Reported by: CHERI
Reviewed by: kp
MFC after: 1 week
Sponsored by: CHERI Research Centre (EPSRC grant UKRI3001)
Differential Revision: https://reviews.freebsd.org/D54163
(cherry picked from commit 796abca7e2)
This is useful when dev.netmap.port_numa_affinity is set to 1. When
interfaces attach, they get a memory allocator that is copied from
nm_mem. Parameters in nm_mem can be set using sysctls, but this happens
after their values are copied.
To work around this, we can make it possible to set these memory
parameters as tunables.
Reviewed by: vmaffione
MFC after: 1 week
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D54178
(cherry picked from commit c694122f3c)
- Add a flag which cleanly indicates that a given process is the system
idle process.
- Modify racctd() to skip over the idle proc when aggregating CPU time
and other metrics which don't apply to the idle thread.
- Remove handling for idle threads from racct_getpcpu().
PR: 269097
Reviewed by: olce, kib
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D50073
(cherry picked from commit 33be163204)
Reported by: Kevin Day <[email protected]>
Approved by: so
Security: FreeBSD-SA-25:12.rtsold
Security: CVE-2025-14558
(cherry picked from commit bf804f69dd)
We bump the object reference count prior to mapping it into the kernel
map, at which point the vm_map_entry owns the reference. Then, if
vm_map_wire() fails, vm_map_remove() will release the reference, so we
should avoid decrementing it in the error path.
Reported by: Ilja van Sprundel <[email protected]>
Reviewed by: vmaffione
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53066
(cherry picked from commit dfc1041c08)
If the length of the string is maxlen, we would end up copying maxlen+1
bytes, which violates the contract of the function. The result is the
same since that extra byte is overwritten.
Reported by: Kevin Day <[email protected]>
Reviewed by: imp, kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D54093
(cherry picked from commit 73586fcea6)
vm_smp_rendezvous() invokes a callback on all vCPUs, blocking the
initiator until all vCPUs have responded. vcpu_lock_all() blocks each
vCPU by waiting for it to go idle and setting the vCPU state to frozen.
These two operations can deadlock on each other, particularly when
booting a Windows guest, when vcpu_lock_all() blocks waiting for a
rendezvous initiator, and the initiator is blocked waiting for the vCPU
thread which called vcpu_lock_all() to invoke the rendezvous callback.
Implement vcpu_lock_all() in a way that avoids deadlocks with
vm_smp_rendezvous(). In particular, when traversing vCPUs, invoke the
rendezvous callback on the vCPU's behalf to help the initiator finish.
We can only safely do so when the vCPU is IDLE or we have already locked
it, otherwise we may be racing with the target vCPU thread. Thus:
- Use an exclusive lock to serialize vcpu_lock_all() callers, which lets
us lock vCPUs out of order without fear of deadlock with parallel
vcpu_lock_all() callers.
- If a rendezvous is pending, lock all idle vCPUs and invoke the
callback on their behalf. If the vcpu_lock_all() caller is itself a
vCPU thread, this will handle that thread.
- Block waiting for all non-idle vCPUs to idle, or until one of them
initiates a rendezvous, in which case we go back and invoke callbacks
on behalf of already-locked vCPUs.
Note that on !amd64 no changes are needed since there is no rendezvous
mechanism, so there is a separate vcpu_set_state_all() for them based on
the previous vcpu_lock_all(). These will be merged together once vcpu
state handling is consolidated into sys/dev/vmm.
Reviewed by: corvink (previous version)
MFC after: 3 weeks
Differential Revision: https://reviews.freebsd.org/D52968
(cherry picked from commit f39768e52e)
In general f_event is supposed to be called with the knlist mutex held,
so lock it earlier to follow this protocol. Also make sure that the
update to kn_fflags is synchronized.
Lock the kqueue itself earlier in the case where the knote is activated,
to avoid locking and unlocking the kqueue twice.
PR: 291005
Reported by: Qiu-ji Chen <[email protected]>
Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53762
(cherry picked from commit d795c753e2)
The handlers were not checking that the group names are nul-terminated.
Add checks for this.
Reported by: Ilja Van Sprundel <[email protected]>
Reviewed by: zlei
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D53344
(cherry picked from commit 32919a34f1)
These structures are copied out to userspace, and it's possible to leak
uninitialized stack bytes since these routines and their callers weren't
careful to clear them first. Add memsets to avoid this.
Reported by: Ilja Van Sprundel <[email protected]>
Reviewed by: kp, emaste
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D53342
(cherry picked from commit ff08916e9a)
It was added to the list in bsd.opts.mk in commit 4f81c42fbd, so
should have been removed here.
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
(cherry picked from commit b2f5dc591e)
(cherry picked from commit 7626ba0280)
PR: 290427
While TCP disallows connect()ing a socket with SO_REUSEPORT_LB, UDP does
not. As a result, a connected UDP socket can be placed in the lbgroup
hash and thus receive datagrams from sources other than the connected
host.
Reported by: Amit Klein <[email protected]>
Reported by: Omer Ben Simhon <[email protected]>
Reviewed by: glebius
Approved by: so
Security: FreeBSD-SA-25:09.netinet
Security: CVE-2025-24934
(cherry picked from commit 320ad3dec5)
In parse_notes we validate that the note name fits within the note
buffer, but we do not do the same for the note data, so there is some
potential for an OOB read in the note handler. Add a bounds check.
Reported by: Ilja Van Sprundel <[email protected]>
Reviewed by: kib, emaste
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53063
(cherry picked from commit c86af2cc4c)
A string array is represented by a set of nul-terminated strings
concatenated together. For each string, we check to see if there's a
nul terminator at the end, taking care to avoid going past the end of
the buffer. However, the code fails to handle the possibility that
size == 0 at the end of an iteration, leading to underflow.
Fix the length check.
Reported by: Ilja van Sprundel <[email protected]>
Reviewed by: emaste
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53069
(cherry picked from commit 937693fc9e)
Note, it looks like this code may be unused since commit 4a77657cbc
("ipfw: migrate ipfw to 32-bit size rule numbers"). In particular, it
looks like the ipfw_nat_*_ptr pointers are unused now.
Reviewed by: ae
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53068
(cherry picked from commit 2df39ce5d4)
In the non-ASLR case, there is no check for an error from
vm_map_fixed(). Restore it, it was dropped in commit 939f0b6323.
This bug could result in a refcount leak of the object used to map the
VDSO page.
Reviewed by: kib
Reported by: Ilja Van Sprundel <[email protected]>
MFC after: 1 week
Fixes: 939f0b6323 ("Implement shared page address randomization")
Differential Revision: https://reviews.freebsd.org/D53065
(cherry picked from commit 7117c86fcb)
- Fail loudly if we can't change the kern.crypto.allow_soft sysctl.
- Add more drivers to the list.
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D52490
(cherry picked from commit e63bf6aa52)
When creating OS images as a non-root user, it may be useful to
pre-create users in the staged tree. The useradd operation adds files
to the new user's home directory, copied from the skeleton directory
(/usr/share/skel), which makes it inconvient for use in this scenario
since the added files are not recorded in the mtree metalog.
To cover this gap, this change adds a new -M <metalog> option to pw's
useradd operation, causing pw to add mtree entries for newly added
files.
Extend an existing regression test to validate this mode.
Reviewed by: bapt, emaste
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D52590
(cherry picked from commit 182ed3c075)
As a bonus, check for I/O errors and print them to standard error.
Reviewed by: bapt, emaste
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D52588
(cherry picked from commit a03d150a3d)
mkdir_home_parents() effectively performs a mkdir -p of the root home
directory. It chowns the home directory to 0, 0, but doesn't do so for
the intermediate directories. Add an explicit chown() call for those
too. Fix a long line while here.
Reviewed by: bapt
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D52587
(cherry picked from commit 41b2a80353)
- Remove a stray backslash.
- Make an error message fit on one line.
No functional change intended.
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
(cherry picked from commit bc69d5dffa)
We do this in most places already, but not consistently.
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
(cherry picked from commit daa63c9417)