Compare commits

...
Author SHA1 Message Date
Colin Percival 58066db597 Update in preparation for 13.4-RELEASE
- Bump BRANCH to RELEASE
- Record the anticipated announcement date in UPDATING
- Set a static __FreeBSD_version in crtbrand.S

Approved by:	re (implicit)
Sponsored by:	Amazon
2024-09-13 00:00:00 +00:00
Dimitry Andric 5096328dd7 Add UPDATING note about running make delete-old after libc++ 18 upgrade
PR:		279692
MFC after:	3 days

(cherry picked from commit 157802238b)
(cherry picked from commit 6b147f693b)

Approved by:	re (cperciva)
2024-09-09 19:49:39 +02:00
Colin Percival 087b246271 13.4: Update to RC3
Approved by:	re (implicit)
Sponsored by:	Amazon
2024-09-05 23:39:08 -07:00
Kristof Provost e893ec49af pf: rework pf_icmp_state_lookup() failure mode
If pf_icmp_state_lookup() finds a state but rejects it for not matching the
expected direction we should unlock the state (and NULL out *state). This
simplifies life for callers, and also ensures there's no confusion about what a
non-NULL returned state means.

Previously it could have been left in there by the caller, resulting in callers
unlocking the same state twice.

MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 0578fe4922)
(cherry picked from commit d6e5f8643d)

Approved-by:	re (cperciva)
2024-09-05 09:35:12 +02:00
Kristof Provost 13bf8945c9 pf: be less strict about icmp state checking for sloppy state tracking
Sloppy state tracking renders ICMP direction check useless
and harmful as we might see only half of the connection in
the asymmetric setups but ignore the state match.  The bug
was reported and fix was verified by Insan Praja <insan ()
ims-solusi ! com>.  Thanks!  OK mcbride, henning

MFC after:	1 week
Obtained from:	OpenBSD, mikeb <[email protected]>, 538596657140
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 3da3eb6081)
(cherry picked from commit b4b8b2fc9b)

Approved-by:	re (cperciva)
2024-09-05 09:35:03 +02:00
Kristof Provost 183076d244 pf: try to lookup the icmp state based on a correct packet descriptor
MFC after:	1 week
Obtained from:	OpenBSD, mikeb <[email protected]>, e467ea25dcd3
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit b8cd169efa)
(cherry picked from commit fa4b648361)

Approved-by:	re (cperciva)
2024-09-05 09:34:52 +02:00
Kristof Provost d3ee218868 pf: improve the ICMPv6 direction check
Following bluhm's advice this changes the way we setup state keys and
perform state lookups for ICMPv6 Neighbor Discovery packets:
  - replace the NS-dst with ND target address;
  - replace the NA-src with ND target address;
  - replace the NA-dst with unspecified address if it is a multicast.

This allows pf to match Address Resolution, Neighbor Unreachability
Detection and Duplicate Address Detection packets to the corresponding
states without the need to create new ones or match unrelated ones.
As a side effect we're doing now one state table lookup for ND packets
instead of two.

Fixes a bug uncovered by one of the previous commits that virtually
breaks IPv6 connectivity after few minutes of use.

ok stsp henning, with and ok bluhm

PR:		280701
MFC after:	1 week
Obtained from:	OpenBSD, mikeb <[email protected]>, 2633ae8c4c8a
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 5ab1e5f7e5)
(cherry picked from commit b843442067)

Approved-by:	re (cperciva)
2024-09-05 09:34:26 +02:00
Jessica Clarke 1d75ce8356 loader.efi.8: Remove rogue duplicated lines
Fixes:		871911a4ab ("loader.efi(8): beef up the updating the ESP")
MFC after:	1 week

(cherry picked from commit 18f7683e0d)
(cherry picked from commit 8aa8d0aa64)

Approved-by: re (cperciva)
2024-09-04 15:54:04 -06:00
Ed Maste 21576f6396 Add UPDATING entries and bump revision
SA-24:09.libnv
SA-24:11.ctl
SA-24:12.bhyve
SA-24:14.umtx

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:32:58 +00:00
Olivier Certner 7739dab974 umtx: shm: 'ushm_refcnt > 0' => 'ushm_refcnt != 0'
'ushm_refcnt' is unsigned.  Don't leave the impression it isn't.

No functional change (intended).

Reviewed by:    kib
Approved by:    emaste (mentor)
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D46126

(cherry picked from commit c75a18905e)
(cherry picked from commit 4938f55446)
(cherry picked from commit a73a70472c)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:16:40 +00:00
Olivier Certner 6000de0966 umtx: shm: Prevent reference counting overflow
This hardens against provoked use-after-free occurences should there be
reference counting leaks in the future (which is currently not the
case).

At the deepest level, umtx_shm_find_reg_unlocked() now returns EOVERFLOW
when it cannot grant an additional reference to the registry object, and
so will umtx_shm_find_reg().  umtx_shm_create_reg() will fail if calling
umtx_shm_find_reg() returns EOVERFLOW (meaning a SHM object for the
passed key already exists, but we can't acquire another reference on
it), avoiding the creation of a duplicate registry entry for a given key
(this wouldn't pose problem for the rest of the code in its current
form, but is expressly avoided for intelligibility and hardening
purposes).

Since umtx_shm_find_reg*(), and consequently the whole _umtx_op() system
call, can only return EOVERFLOW on such a bug manifesting, we don't
document that return value.

Reviewed by:    kib, emaste
Approved by:    emaste (mentor)
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D46126

(cherry picked from commit c3e6dfe55c)
(cherry picked from commit b20ae16087)
(cherry picked from commit 8cf43dcd3d)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:16:30 +00:00
Olivier Certner abb0a18b69 umtx: shm: Fix use-after-free due to multiple drops of the registry reference
umtx_shm_unref_reg_locked() would unconditionally drop the "registry"
reference, tied to USHMF_LINKED.

This is not a problem for caller umtx_shm_object_terminated(), which
operates under the 'umtx_shm_lock' lock end-to-end, but it is for
indirect caller umtx_shm(), which drops the lock between
umtx_shm_find_reg() and the call to umtx_shm_unref_reg(true) that
deregisters the umtx shared region (from 'umtx_shm_registry';
umtx_shm_find_reg() only finds registered shared mutexes).

Thus, two concurrent user-space callers of _umtx_op() with UMTX_OP_SHM
and flags UMTX_SHM_DESTROY, both progressing past umtx_shm_find_reg()
but before umtx_shm_unref_reg(true), would then decrease twice the
reference count for the single reference standing for the shared mutex's
registration.

Reported by:    Synacktiv
Reviewed by:    kib
Approved by:    emaste (mentor)
Security:	FreeBSD-SA-24:14.umtx
Security:	CVE-2024-43102
Security:       CAP-01
Sponsored by:   The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D46126

(cherry picked from commit 62f40433ab)
(cherry picked from commit be7dc46139)
(cherry picked from commit 40615bcae9)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:14:57 +00:00
Olivier Certner a667c04946 umtx: shm: Collapse USHMF_REG_LINKED and USHMF_OBJ_LINKED flags
...into the only USHMF_LINKED, as they are always set or unset together.

This is both to stop giving the impression that they can be set/unset
independently, which they can't with the current code, and to make it
clearer that an upcoming reference counting fix is correct.

Reviewed by:    kib
Approved by:    emaste (mentor)
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D46126

(cherry picked from commit dd83da532c)
(cherry picked from commit 2d4511bb81)
(cherry picked from commit 5f49630fef)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:14:46 +00:00
Pierre Pronchery b3f0e55578 bhyve: fix off by one error in pci_xhci
The function pci_xhci_find_stream validates that the streamid is valid
but the bound check accepts up to ep_MaxPStreams included.

The bug results in an out-of-bounds write on the heap with controlled
data.

Reported by:	Synacktiv
Reviewed by:	jhb
Security:	FreeBSD-SA-24:12.bhyve
Security:	CVE-2024-32668
Security:	HYP-04
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D45994

(cherry picked from commit 5c9308a413)
(cherry picked from commit 90af1336ed)
(cherry picked from commit 5920b7e6ee)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:14:35 +00:00
Pierre Pronchery 0042987920 ctl: fix Out-Of-Bounds access in ctl_report_supported_opcodes
This vulnerability is directly accessible to a guest VM through the
pci_virtio_scsi bhyve device.

In the function ctl_report_supported_opcodes() accessible from the VM,
the option RSO_OPTIONS_OC_ASA does not check the requested
service_action value before accessing &ctl_cmd_table[].

Reported by:	Synacktiv
Reviewed by:	asomers
Security:	FreeBSD-SA-24:11.ctl
Security:	CVE-2024-42416
Security:	HYP-06
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D46027

(cherry picked from commit af438acbfd)
(cherry picked from commit 803e0c2ab2)
(cherry picked from commit c8afc07269)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:14:25 +00:00
Pierre Pronchery 98e8cb3d94 ctl: fix memory disclosure in read/write buffer commands
The functions ctl_write_buffer() and ctl_read_buffer() are vulnerable to
a kernel memory disclosure caused by an uninitialized kernel allocation.
If one of these functions is called for the first time for a given LUN, a
kernel allocation is performed without the M_ZERO flag. Then a call to
ctl_read_buffer() returns the content of this allocation, which may
contain kernel data.

Reported by:	Synacktiv
Reviewed by:	asomers
Reviewed by:	jhb
Security:	FreeBSD-SA-24:11.ctl
Security:	CVE-2024-8178
Security:	HYP-05
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D45952

(cherry picked from commit ea44766b78)
(cherry picked from commit cdfdb3b008)
(cherry picked from commit b13631a59f)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:14:14 +00:00
Alan Somers 29fbeb5c59 ctl: fix Use-After-Free in ctl_write_buffer
The virtio_scsi device allows a guest VM to directly send SCSI commands
to the kernel driver exposed on /dev/cam/ctl. This setup makes the
vulnerability directly accessible from VMs through the pci_virtio_scsi
bhyve device.

The function ctl_write_buffer sets the CTL_FLAG_ALLOCATED flag, causing
the kern_data_ptr to be freed when the command finishes processing.
However, the buffer is still stored in lun->write_buffer, leading to a
Use-After-Free vulnerability.

Since the buffer needs to persist indefinitely, so it can be accessed by
READ BUFFER, do not set CTL_FLAG_ALLOCATED.

Reported by:	Synacktiv
Reviewed by:	Pierre Pronchery <[email protected]>
Reviewed by:	jhb
Security:	FreeBSD-SA-24:11.ctl
Security:	CVE-2024-45063
Security:	HYP-03
Sponsored by:	Axcient
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D46424

(cherry picked from commit 670b582db6)
(cherry picked from commit 29937d7a1a)
(cherry picked from commit 2553c91f73)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:13:45 +00:00
Mariusz Zaborski 3aa9be7e33 libnv: verify that string is null terminated
During unpacking, we ensure that we do not read beyond the
declared size. However, unpack uses a function that copies
null-terminated strings. Prior to this commit, if the last string
was not null-terminated, it could result in copying data into a
buffer smaller than the allocated size.

Security:       FreeBSD-24:09.libnv
Security:       CVE-2024-45288
Security:       CAP-03
Reported by:    Synacktiv
Sponsored by:   The Alpha-Omega Project
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D46138

(cherry picked from commit 3aaaca1b51)
(cherry picked from commit 03bef9971d)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:10:30 +00:00
Mariusz Zaborski a8d0ba4833 libnv: allocate buffer in a safe way
Ensure that the calculation of size of array doesn't
overflow.

Security:	FreeBSD-24:09.libnv
Security:	CVE-2024-45287
Security:	CAP-02
Reported by:	Synacktiv
Reported by:	Taylor R Campbell (NetBSD)
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D46131

(cherry picked from commit 36fa90dbde)
(cherry picked from commit 2e7f9244eb)

Approved by:	so
Approved by:	re (cperciva)
2024-09-04 19:10:18 +00:00
Colin Percival 73da0e55aa 13.4: Update to RC2
Approved by:	re (implicit)
Sponsored by:	Amazon
2024-08-29 17:45:01 -07:00
Warner Losh faf94e22a3 loader.efi(8): beef up the updating the ESP
There's a huge variety of situations when booting with UEFI. Document
more of them, hopefully better.

Feedback from: jrtc27
MFC After: 3 days
Sponsored by:		Netflix

(cherry picked from commit 871911a4ab)
(cherry picked from commit e95ffda78a)

Approved-by: re (cperciva)
2024-08-29 12:50:49 -06:00
Ed Maste 27777283da ctl: avoid heap info leak in ctl_request_sense
Previously 3 bytes of data from the heap could be leaked to ctl
consumers.

Reported by:	Synacktiv
Reviewed by:	asomers, mav
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D46091

(cherry picked from commit db87c98168)
(cherry picked from commit 131b7dcb2f)
(cherry picked from commit 51768dc31d)

Approved by:	re (cperciva)
2024-08-26 14:29:40 -04:00
Oliver Fromme e381992365 amdsmn(4), amdtemp(4): add support for AMD Ryzen 7 "Phoenix" processors
Adds support for AMD Ryzen 7 "Phoenix" processors (family 0x19,
model 0x70-0x7f) to the amdsmn(4) and amdtemp(4) drivers. This
enables temperature readings of these CPUs via sysctl.

The sensors function identically to those for the "Raphael" processors
(model 0x60-0x6f); only the PCI device ID differs.

PR:		kern/280942
Relnotes:	yes
Approved by:	re (cperciva)

(cherry picked from commit ef3f8aa0a0)
(cherry picked from commit cb8f15aeed)
2024-08-26 08:21:13 -07:00
Colin Percival 700ff8f05f 13.4: Update to RC1
Approved by:	re (implicit)
Sponsored by:	Amazon
2024-08-22 17:06:43 -07:00
Colin Percival 3b8f0ffc0f 13.4: Switch from "quarterly" to "release" pkgs
Approved by:	re (implicit)
Sponsored by:	Amazon
2024-08-22 15:11:08 -07:00
Colin Percival 2006e3634b Modernize DVD package set in preparation for 14.1
[MFC note: We're making the same changes for 13.4.]

Remove archivers/unzip (now in base) and emulators/linux_base-c7 (old
and unlikely to be useful without other linux packages being installed),
ports-mgmt/portmaster (now largely obsolete and discouraged in favour
of using pkg and binary packages) and x11-drivers/xf86-video-vmware
(questionably useful).

Replace devel/git with devel/git@lite (sufficient for most purposes),
and adjust the "ensure the ports exist to sanitize the list" code to
ignore the @lite part when checking that /usr/ports/devel/git exists.

Add sysutils/seatd and x11-wm/sway for wayland support.

Approved by:	re (cperciva)
MFC after:	1 minute
Differential Revision:	https://reviews.freebsd.org/D45278

(cherry picked from commit a926bf9254)
2024-08-22 15:01:22 -07:00
Graham Perrin 7bcf0d3320 pkg-stage.sh: add x11/sddm
Approved by:	re (cperciva)
MFC After: 2 days
Reviewed by: imp
Pull Request: https://github.com/freebsd/freebsd-src/pull/996

(cherry picked from commit 6becc61b94)
2024-08-22 15:01:07 -07:00
Mike Karels 7847d5e56c pw userdel: destroy home dataset if empty
When removing a user's home directory, if the directory is a ZFS
dataset, it cannot be removed.  If the directory has been emptied,
use "zfs destroy" to destroy it.  This complements the automatic
dataset creation in adduser.  Note that datasets within the directory
and snapshots are not handled, as the complete path is not constructed.

While here, add waitpid() calls to rmat() and pw_user_del().

Reviewed by:	des
Differential Revision:	https://reviews.freebsd.org/D45348
Approved by:	re (cperciva)

(cherry picked from commit d2f1f71ec8)
(cherry picked from commit cd13258d26)
2024-08-21 19:13:40 +02:00
Dag-Erling Smørgrav eb7bf0d071 adduser: Better document ZFS dataset creation.
MFC after:	3 days
PR:		280873
Reviewed by:	bcr
Differential Revision:	https://reviews.freebsd.org/D46316
Approved by:	re (cperciva)

(cherry picked from commit 9ff2ebd928)
(cherry picked from commit 8398c81b7c)
2024-08-21 19:13:33 +02:00
Mike Karels 0ebe6df086 adduser: create dataset only if home is directly within dataset
Currently, if the prefix of the new home directory is a subdirectory
of a ZFS dataset, adduser will create a new dataset up one or more
levels from the intended destination.  "pw useradd" will then create
a normal directory in the desired location, leaving an unused dataset.
Check for this situation when determining whether to create a dataset,
and let pw create the directory.

Reviewed by:	des
Differential Revision:	https://reviews.freebsd.org/D45229
MFC after:	3 days
Approved by:	re (cperciva)

(cherry picked from commit 0b39b2e2dd)
(cherry picked from commit da384ffbd5)
2024-08-21 19:13:22 +02:00
Andre Albsmeier 9b945635c1 tail -F: fix crash
PR:	280910
Approved by:	re (cperciva)

(cherry picked from commit 308399a179)
(cherry picked from commit 8dfa4e5b6c)
2024-08-21 18:59:21 +03:00
Kristof Provost 9c67287ccf pf: invert direction for inner icmp state lookups
(e.g. traceroute with icmp)
ok henning, jsing

Also extend the test case to cover this scenario.

PR:		280701
Approved by:	re (cperciva)
Obtained from:	OpenBSD
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 89f6723288)
(cherry picked from commit 5f3f07397a)
2024-08-21 09:44:25 +02:00
Kristof Provost 6a7bac2ae7 pf tests: ensure that traceroutes using ICMP work
PR:		280701
Approved by:	re (cperciva)
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 34063cb714)
(cherry picked from commit 7024e1066d)
2024-08-21 09:44:16 +02:00
Kristof Provost 7d3a0370c8 pf: fix icmp-in-icmp state lookup
In 534ee17e6 pf state checking for ICMP(v6) was made stricter. This change
failed to correctly set the pf_pdesc for ICMP-in-ICMP lookups, resulting in ICMP
error packets potentially being dropped incorrectly.
Specially, it copied the ICMP header into a separate variable, not into the
pf_pdesc.

Populate the required pf_pdesc fields for the embedded ICMP packet's state lookup.

PR:		280701
Approved by:	re (cperciva)
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 2da98eef1f)
(cherry picked from commit 0d8d4cc3ea)
2024-08-21 09:44:01 +02:00
Colin Percival abf370e400 13.4: Update to BETA3
Approved by:	re (implicit)
Sponsored by:	Amazon
2024-08-15 17:05:08 -07:00
Stefan Eßer d5c1fa0ec0 msdosfs: fix cluster limit when mounting FAT-16 file systems
The maximum cluster number was calculated based on the number of data
cluters that fit in the givem partition size and the size of the FAT
area. This limit did not take into account that the highest 10 cluster
numbers are reserved and must not be used for files.

Approved by:	re
PR:		280347
Reported by:	[email protected]

(cherry picked from commit 45d4e82bf6)
(cherry picked from commit e8f52a86ee)
2024-08-15 23:46:57 +02:00
Dimitry Andric e664cd1dc5 Fix EFI loader reproducibility with lld
When the various loaders under stand/efi are built, the resulting
binaries differ over multiple runs, even if WITH_REPRODUCIBLE_BUILD is
used. This is caused by lld multithreading and the custom linker scripts
for the loaders, and affects the following binaries:

* loader_4th.efi
* loader_4th.sym
* loader_4th.sym.full
* loader_lua.efi
* loader_lua.sym
* loader_lua.sym.full
* loader_simp.efi
* loader_simp.sym
* loader_simp.sym.full

Work around this by disabling lld threading for these binaries.

Reviewed by:	emaste
Approved by:	re (cperciva)
MFC after:	3 days
Differential Revision: https://reviews.freebsd.org/D46271

(cherry picked from commit f5ce3f4ef5)
(cherry picked from commit 8a4fd438ef)
2024-08-15 09:42:36 +02:00
Kyle Evans 7088bf662d calendar: don't setlogin(2) in the -a user handlers
As of e67975d331 ("Fix 'calendar -a' in several ways."), `calendar -a`
will now fork off a new process for each user and do all of its own
processing in the user's own context.

As a side-effect, calendar(1) started calling setlogin(2) in each of the
forked processes and inadvertently hijacked the login name for the
session it was running under, which was typically not a fresh session
but rather that of whatever cron/periodic run spawned it.  Thus, daily
and security e-mails started coming from completely arbitrary user.

We could create a new session, but it appears that nothing calendar(1)
does really needs the login name to be clobbered; opt to just avoid the
setlogin(2) call entirely rather than incur the overhead of a new
session for each process.

PR:		280418
Reviewed by:	des, olce
Approved by:	re (cperciva)
Fixes:		e67975d331 ("Fix 'calendar -a' in several ways.")

(cherry picked from commit 6cb8b61efe)
(cherry picked from commit 3a9010c98b)
2024-08-13 22:36:52 -05:00
Dimitry Andric 140f361aa6 Merge commit d2353ae00c3b from llvm git (by Argyrios Kyrtzidis):
[utils/TableGen/X86CompressEVEXTablesEmitter.cpp] Make sure the tablegen output for the `checkPredicate` function is deterministic (#84533)

  The output for the `checkPredicate` function was depending on a
  `std::map` iteration that was non-deterministic from run to run, because
  the keys were pointer values.

  Make a change so that the keys are `StringRef`s so the ordering is
  stable.

This avoids non-determinism in llvm-tblgen output, which could cause
differences in the generated X86GenCompressEVEXTables.inc file. Although
these differences are not influencing the meaning of the generated code,
they still change a few bytes in libllvm. This in turn influences all
the binaries linked with libllvm, such as clang, ld.lld, etc.

Reported by:	cperciva
Approved by:	re (cperciva)
MFC after:	3 days

(cherry picked from commit 7a8d05ba19)
(cherry picked from commit 4dac78525c)
2024-08-13 18:59:05 +02:00
Pierre Pronchery 1b30c5d3a5 acl_copyin: avoid returning uninitialized memory
acl_copyin did not validate the return value of acl_copy_oldacl_into_acl
which could lead to uninitialized acl structure memory reads.

Reported by:    Synacktiv
Reviewed by:	markj, emaste
Sponsored by:   The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D46125

(cherry picked from commit 6ee6c7b146)
(cherry picked from commit 6bf5c32ad8)
(cherry picked from commit 8f16d9f7dc)

Approved by:	re (cperciva)
2024-08-13 12:43:58 -04:00
Ed Maste 8807350405 pipe: keep uio_iovcnt consistent
In pipe_build_write_buffer we increment uio_iov but did not update
uio_iovcnt.  This would not cause an OOB read (thanks to to uio_resid)
but is inconsistent and could be an issue if other code changes are made
in the future.

Reported by:	Synacktiv
Reviewed by:	jhb, markj, brooks
Sponsored by:	The Alpha-Omega Project
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D45999

(cherry picked from commit d8ff42e816)
(cherry picked from commit cbbc8d6730)
(cherry picked from commit 0fb9da95f7)

Approved by:	re (cperciva)
2024-08-13 12:39:56 -04:00
Dmitry Morozovsky 246e27fa98 mailer.conf for sendmail: remove duplicate word.
MFC after:	3 days
Approved by:	re (cperciva@)

(cherry picked from commit 2c2916a3ec)
(cherry picked from commit 3d2b2d8d02)
2024-08-12 19:49:57 +03:00
Michael Tuexen 6a0215b2e3 tcp: initialize V_ts_offset_secret for all vnets
Initialize V_ts_offset_secret for each vnet, not only for the
default vnet, since it is vnet specific.

Reviewed by:		Peter Lei
Sponsored by:		Netflix, Inc.
Approved by:		re (cperciva@)
Differential Revision:	https://reviews.freebsd.org/D46246

(cherry picked from commit 9b569353e0)
(cherry picked from commit 83572ae1f5)
2024-08-12 18:40:51 +02:00
Colin Percival 30b27afe3b 13.4: update to BETA2
Approved by:	re (implicit)
Sponsored by:	Amazon
2024-08-08 17:11:33 -07:00
Mark Johnston 751c889691 nd6: Fix the routing table subscription
The nd6 code listens for RTM_DELETE events so that it can mark the
corresponding default router as inactive in the case where the default
route is deleted.  A subsequent RA from the router may then reinstall
the default route.

Commit fedeb08b6a broke this for non-multipath routes, as
rib_decompose_notification() only invokes the callback for multipath
routes.  Restore the old behaviour.  Also ensure that we update the
router only for RTM_DELETE notifications, lost in commit 2259a03020.

Approved by:	re (cperciva)
Reviewed by:	bz
Fixes:	fedeb08b6a ("Introduce scalable route multipath.")
Fixes:	2259a03020 ("Rework part of routing code to reduce difference to D26449.")
MFC after:	2 weeks
Sponsored by:	Klara, Inc.
Sponsored by:	Bell Tower Integration
Differential Revision:	https://reviews.freebsd.org/D46020

(cherry picked from commit a48df53e42)
(cherry picked from commit c611f050d0dc01bf1f738300365895da84aa5fef)
2024-08-08 22:41:29 +00:00
Mark Johnston 4bf6ca0e71 cxgbe: Flush transmitted packets more regularly in netmap mode
Previously, when transmitting short runs of packets via cxgbe_nm_tx(),
we would wait until a large number of packets were buffered before
scheduling a task to clean transmit buffers.

Approved by:	re (cperciva)
Obtained from:	np

(cherry picked from commit 6af3d59962)
(cherry picked from commit 59a9c20d77)
2024-08-08 17:13:56 +00:00
Mark Johnston a87a597313 ktrace: Fix an inverted privilege check
Approved by:	so
Approved by:	re (cperciva)
Security:	FreeBSD-SA-24:06.ktrace
Security:	CVE-2024-6760
Fixes:	1762f674cc ("ktrace: pack all ktrace parameters into allocated structure ktr_io_params")

(cherry picked from commit 166b7573b5)
(cherry picked from commit f702110bc4)
2024-08-07 15:43:39 +00:00
Ed Maste bd3aa40e0a sshd: remove blacklist call from grace_alarm_timer
Under certain circumstances it may call log(3), which is not async-
signal-safe.

For now just remove the blacklist integration from this path, which
means that blacklistd will not detect and firewall hosts that establish
a connection but do nothing further.

Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D46203

(cherry picked from commit 2739a68450)
(cherry picked from commit 3d3bae9b95)
(cherry picked from commit 73466449a9)
(cherry picked from commit d5f16ef646)

Approved by:	re (cperciva)
2024-08-07 11:39:06 -04:00
Michael Tuexen 9badd542e7 sctp: improve input validation for data chunks
fsn_included should only be considered, if first_frag_seen is true.
Also, fix the resetting of the control structure, if stream queues
are flushed.
This fixes a bug where a legitimate message sequence was incorrectly
classified as illegitimate.
Thanks to Victor Boivie for reporting the issue on the userland
stack.

(cherry picked from commit 101a0f09e8)
(cherry picked from commit 18f4b70573)

Approved by:	re (cperciva)
2024-08-07 00:36:18 +02:00
Colin Percival e192230d0d 13.4: create releng/13.4 branch
Update from PRERELEASE to BETA1
Switch pkg(8) configuration to use the quarterly repository
Bump __FreeBSD_version

Approved by:	re (implicit)
Sponsored by:	Amazon
2024-08-01 17:05:49 -07:00
45 changed files with 758 additions and 263 deletions

No files matched your search

+24
View File
@@ -12,6 +12,30 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before updating system packages
and/or ports.
20240917:
13.4-RELEASE.
20240904:
13.4-RC2-p1 SA-24:09.libnv
SA-24:11.ctl
SA-24:12.bhyve
SA-24:14.umtx
Multiple vulnerabilities in libnv [SA-24:09.libnv]
Multiple issues in ctl(4) CAM Target Layer [SA-24:11.ctl]
bhyve(8) privileged guest escape via USB controller [SA-24:12.bhyve]
umtx Kernel panic or Use-After-Free [SA-24:14.umtx]
20240419:
Clang, llvm, lld, lldb, compiler-rt, libc++, libunwind and openmp have
been upgraded to 18.1.6. It is important that you run `make delete-old`
as described in the COMMON ITEMS section, otherwise several libc++
headers that are obsolete and need to be removed can cause compilation
errors in C++ programs.
20240218:
MFC of 713db49d06de changed 'struct ieee80211vap' internals in net80211.
Given we do not have enough spares and the struct is allocated by
@@ -46,7 +46,7 @@ class X86CompressEVEXTablesEmitter {
typedef std::pair<const CodeGenInstruction *, const CodeGenInstruction *>
Entry;
typedef std::map<const Record *, std::vector<const CodeGenInstruction *>>
typedef std::map<StringRef, std::vector<const CodeGenInstruction *>>
PredicateInstMap;
std::vector<Entry> Table;
@@ -89,7 +89,7 @@ void X86CompressEVEXTablesEmitter::printCheckPredicate(
for (const auto &[Key, Val] : PredicateInsts) {
for (const auto &Inst : Val)
OS << " case X86::" << Inst->TheDef->getName() << ":\n";
OS << " return " << Key->getValueAsString("CondString") << ";\n";
OS << " return " << Key << ";\n";
}
OS << " }\n";
@@ -226,7 +226,7 @@ void X86CompressEVEXTablesEmitter::run(raw_ostream &OS) {
Name == "HasAVXIFMA";
});
if(It!= Predicates.end())
PredicateInsts[*It].push_back(NewInst);
PredicateInsts[(*It)->getValueAsString("CondString")].push_back(NewInst);
}
printTable(Table, OS);
+1 -1
View File
@@ -44,4 +44,4 @@
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
# UserKnownHostsFile ~/.ssh/known_hosts.d/%k
# VersionAddendum FreeBSD-20240318
# VersionAddendum FreeBSD-20240806
+1 -1
View File
@@ -2137,7 +2137,7 @@ in
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20240318 .
.Dq FreeBSD-20240806 .
The value
.Cm none
may be used to disable this.
-2
View File
@@ -377,8 +377,6 @@ grace_alarm_handler(int sig)
kill(0, SIGTERM);
}
BLACKLIST_NOTIFY(the_active_state, BLACKLIST_AUTH_FAIL, "ssh");
/* Log error and exit. */
sigdie("Timeout before authentication for %s port %d",
ssh_remote_ipaddr(the_active_state),
+1 -1
View File
@@ -105,7 +105,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#PermitTunnel no
#ChrootDirectory none
#UseBlacklist no
#VersionAddendum FreeBSD-20240318
#VersionAddendum FreeBSD-20240806
# no default banner path
#Banner none
+1 -1
View File
@@ -1947,7 +1947,7 @@ The default is
Optionally specifies additional text to append to the SSH protocol banner
sent by the server upon connection.
The default is
.Qq FreeBSD-20240318 .
.Qq FreeBSD-20240806 .
The value
.Cm none
may be used to disable this.
+1 -1
View File
@@ -5,4 +5,4 @@
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
#define SSH_VERSION_FREEBSD "FreeBSD-20240701"
#define SSH_VERSION_FREEBSD "FreeBSD-20240806"
+1 -1
View File
@@ -1,7 +1,7 @@
#
# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail
#
# If dma(8) is installed, an example mailer.conf that uses dma(8) instead can
# If dma(8) is installed, an example mailer.conf that uses dma(8) instead
# can be found in /usr/share/examples/dma.
#
sendmail /usr/libexec/sendmail/sendmail
+1 -1
View File
@@ -43,7 +43,7 @@
.4byte NT_FREEBSD_ABI_TAG
1: .asciz NOTE_FREEBSD_VENDOR
2: .p2align 2
3: .4byte __FreeBSD_version
3: .4byte 1304000
4:
.section .note.GNU-stack,"",%progbits
+1 -1
View File
@@ -1,5 +1,5 @@
release: {
url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
url: "pkg+http://pkg.FreeBSD.org/${ABI}/release_4",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
+7 -8
View File
@@ -12,27 +12,26 @@ export ROOTDIR="$PWD/dvd"
export PKGCMD="/usr/sbin/pkg -d --rootdir ${ROOTDIR}"
export PORTSDIR="${PORTSDIR:-/usr/ports}"
_DVD_PACKAGES="archivers/unzip
devel/git
emulators/linux_base-c7
_DVD_PACKAGES="devel/git@lite
graphics/drm-kmod
graphics/drm-510-kmod
misc/freebsd-doc-all
net/mpd5
net/rsync
ports-mgmt/pkg
ports-mgmt/portmaster
shells/bash
shells/zsh
security/sudo
sysutils/screen
sysutils/seatd
sysutils/tmux
www/firefox
www/links
x11-drivers/xf86-video-vmware
x11/gnome
x11/kde5
x11/xorg"
x11/sddm
x11/xorg
x11-wm/sway"
# If NOPORTS is set for the release, do not attempt to build pkg(8).
if [ ! -f ${PORTSDIR}/Makefile ]; then
@@ -59,10 +58,10 @@ fi
# Ensure the ports listed in _DVD_PACKAGES exist to sanitize the
# final list.
for _P in ${_DVD_PACKAGES}; do
if [ -d "${PORTSDIR}/${_P}" ]; then
if [ -d "${PORTSDIR}/${_P%%@*}" ]; then
DVD_PACKAGES="${DVD_PACKAGES} ${_P}"
else
echo "*** Skipping nonexistent port: ${_P}"
echo "*** Skipping nonexistent port: ${_P%%@*}"
fi
done
+5
View File
@@ -105,6 +105,11 @@ LDFLAGS+= -Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -pie
LDFLAGS+= -Wl,--no-dynamic-linker
.endif
# When lld is using multiple threads, which it does by default, it can
# result in non-reproducible output with the custom linker script. Work
# around this by disabling threading.
LDFLAGS.lld+= -Wl,--threads=1
CLEANFILES+= ${LOADER}.efi
${LOADER}.efi: ${PROG}
+117 -22
View File
@@ -30,7 +30,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd September 4, 2022
.Dd September 3, 2024
.Dt LOADER.EFI 8
.Os
.Sh NAME
@@ -345,43 +345,138 @@ The default location for the ESP mount point is documented in
The following examples shows how to install a new
.Nm
on the ESP.
The exact placement is complicated due to the diversity of
installations, setups and situations.
In this section, paths that are all lower case are Unix paths.
Paths that are all upper case are relative to the ESP mount point,
though they may appear as lower case on your system because the
FAT filesystem of the ESP is case insensitive.
.Pp
First, find the partition of type
Locate the ESP, which has its own partition type of
.Dq efi :
.Bd -literal -offset indent
# gpart list | grep -Ew '(Name|efi)'
1. Name: nvd0p1
type: efi
2. Name: nvd0p2
3. Name: nvd0p3
4. Name: nvd0p4
1. Name: nvd0
# gpart show nda0
=> 40 7501476448 nda0 GPT (3.5T)
40 614400 1 efi (300M)
614440 7500862048 2 freebsd-zfs (3.5T)
.Ed
.Pp
The name of the ESP on this system is
.Pa nvd0p1 .
.Pa nda0p1 .
By default, this will be mounted on
.Pa /boot/efi .
To check:
.Bd -literal -offset indent
# mount | grep nda0p1
/dev/nda0p1 on /boot/efi (msdosfs, local)
.Ed
If it's not mounted, you will need to mount it:
.Bd -literal -offset indent
# mount -t msdosfs /dev/nda0p1 /boot/efi
.Ed
.Pp
Second, let's mount the ESP, copy
.Nm
to the special location reserved for
.Fx
EFI loaders, and unmount once finished:
.Xr efibootmgr 8
reports what we booted from.
.Bd -literal -offset indent
# efibootmgr -v
Boot to FW : false
BootCurrent: 0001
Timeout : 2 seconds
BootOrder : 0000, 0001, 0003, 0004, 0005, 0006, 0001, 0008, 000A, 000B, 000C, 000E, 0007
...
+Boot0001* FreeBSD ZPOOL HD(1,GPT,b5d0f86b-265d-1e1b-18aa-0ed55e1e73bd,0x28,0x96000)/File(\EFI\FREEBSD\LOADER.EFI)
nda0p1:/EFI/FREEBSD/LOADER.EFI /boot/efi//EFI/FREEBSD/LOADER.EFI
...
.Ed
Often there are several options, depending on the BIOS.
The entry that we booted with is marked with a
.Sq +
at the start of the line, as shown above.
So in this case, this firmware is using
.Pa /EFI/FREEBSD/LOADER.EFI
from the ESP.
Often times it will be the UEFI
.Dq default
loader, which varies by architecture.
.Bl -column -offset indent "Architecture" "Default Path"
.It Sy Architecture Ta Sy Default Path
.It amd64 Ta Pa /EFI/BOOT/BOOTX64.EFI
.It arm Ta Pa /EFI/BOOT/BOOTARM.EFI
.It arm64 Ta Pa /EFI/BOOT/BOOTAA64.EFI
.It i386 Ta Pa /EFI/BOOT/BOOTIA32.EFI
.It riscv Ta Pa /EFI/BOOT/BOOTRISCV64.EFI
.El
However, care must be taken: some multiple-boot environments rely on a special
.Pa bootXXX.efi
to function.
Before updating a
.Pa bootXXX.efi
file, make sure it is the FreeBSD boot loader before updating it:
.Bd -literal -offset indent
# strings /boot/efi/EFI/BOOT/BOOTX64.EFI | grep FreeBSD | grep EFI
FreeBSD/amd64 EFI loader, Revision 3.0
.Ed
.Pp
.Xr bsdinstall 8
copies
.Pa loader.efi
to the default name if there wasn't one there before.
Check to see if they are copies before updating (with X64 substituted using the
above table):
.Bd -literal -offset indent
# cmp /boot/efi/EFI/FREEBSD/LOADER.EFI /boot/efi/EFI/BOOT/BOOOTX64.EFI
.Ed
Copy the loader:
.Bd -literal -offset indent
# cp /boot/loader.efi /boot/efi/EFI/FREEBSD/LOADER.EFI
.Ed
replacing the all caps part of the example with the proper path.
.Pp
If ESP path was
.Pa /FREEBSD/LOADER.EFI
and LOADER.EFI and BOOTX64.EFI were identical in the cmp step,
copy the loader to the default location:
.Bd -literal -offset indent
# cp /boot/loader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
.Ed
.Pp
Finally, if you mounted the ESP, you may wish to unmount it.
.Bd -literal -offset indent
# mount_msdosfs /dev/nvd0p1 /boot/efi
# cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi
# umount /boot/efi
.Ed
.Sh SEE ALSO
.Xr loader 8 ,
.Xr uefi 8
.Sh BUGS
Systems that do not have a
.Dv ConOut
variable set are not conformant with the standard, and likely have unexpected
results.
.Pp
Non-x86 serial console handling is even more confusing and less well documented.
.Pp
Sometimes when the serial port speed isn't set, 9600 is used.
Other times the result is typically 115200 since the speed remains unchanged
from the default.
.Pp
U-Boot implements a subset of the UEFI standard.
Some versions do not support fetching loader variables, so
.Pa efibootmgr
may not work.
In addition,
.Pa efibootmgr
is not supported on armv7 or riscv.
In these instances, the user has to understand what was booted to update
it properly (and in most cases, it will be the FreeBSD path and the UEFI default
so just copy loader.efi there if there are loaders there).
Typically in these embedded situations, there is only one .efi file (loader.efi
or a copy of loader.efi).
The path to this file is typically the default removable path above.
.Pp
Managing booting multiple OSes on UEFI varies greatly, so extra caution when
updating the UEFI default loader.
.Pp
The old, now obsolete, boot1.efi was installed as bootx64.efi in
.Fx 10
and earlier.
Since it was quite limited in functionality, we created very small
ESPs by default.
A modern loader.efi will not fit.
However, if the old boot1.efi still works, there's no need to update
it since it will chain boot /boot/loader.efi from a copy that
make installworld updates.
+22 -26
View File
@@ -5633,7 +5633,7 @@ ctl_read_buffer(struct ctl_scsiio *ctsio)
} else {
if (lun->write_buffer == NULL) {
lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE,
M_CTL, M_WAITOK);
M_CTL, M_WAITOK | M_ZERO);
}
ctsio->kern_data_ptr = lun->write_buffer + buffer_offset;
}
@@ -5672,21 +5672,24 @@ ctl_write_buffer(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
if (lun->write_buffer == NULL) {
lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE,
M_CTL, M_WAITOK | M_ZERO);
}
/*
* If we've got a kernel request that hasn't been malloced yet,
* malloc it and tell the caller the data buffer is here.
* If this kernel request hasn't started yet, initialize the data
* buffer to the correct region of the LUN's write buffer. Note that
* this doesn't set CTL_FLAG_ALLOCATED since this points into a
* persistent buffer belonging to the LUN rather than a buffer
* dedicated to this request.
*/
if ((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) {
if (lun->write_buffer == NULL) {
lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE,
M_CTL, M_WAITOK);
}
if (ctsio->kern_data_ptr == NULL) {
ctsio->kern_data_ptr = lun->write_buffer + buffer_offset;
ctsio->kern_data_len = len;
ctsio->kern_total_len = len;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
ctsio->be_move_done = ctl_config_move_done;
ctl_datamove((union ctl_io *)ctsio);
@@ -7510,20 +7513,19 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
case RSO_OPTIONS_OC_SA:
if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0 ||
service_action >= 32) {
ctl_set_invalid_field(/*ctsio*/ ctsio,
/*sks_valid*/ 1,
/*command*/ 1,
/*field*/ 2,
/*bit_valid*/ 1,
/*bit*/ 2);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
goto invalid;
}
/* FALLTHROUGH */
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
break;
case RSO_OPTIONS_OC_ASA:
if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) != 0 &&
service_action >= 32) {
goto invalid;
}
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32;
break;
default:
invalid:
ctl_set_invalid_field(/*ctsio*/ ctsio,
/*sks_valid*/ 1,
/*command*/ 1,
@@ -9339,14 +9341,8 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
sense_ptr = (struct scsi_sense_data *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
ctsio->kern_rel_offset = 0;
/*
* struct scsi_sense_data, which is currently set to 256 bytes, is
* larger than the largest allowed value for the length field in the
* REQUEST SENSE CDB, which is 252 bytes as of SPC-4.
*/
ctsio->kern_data_len = cdb->length;
ctsio->kern_total_len = cdb->length;
ctsio->kern_data_len = ctsio->kern_total_len =
MIN(cdb->length, sizeof(*sense_ptr));
/*
* If we don't have a LUN, we don't have any pending sense.
+8
View File
@@ -410,6 +410,14 @@ struct ctl_lun {
uint8_t pr_res_type;
int prevent_count;
uint32_t *prevent;
/*
* The READ_BUFFER and WRITE_BUFFER commands permit access to a logical
* data buffer associated with a LUN. Accesses to the data buffer do
* not affect data stored on the storage medium. To support this,
* allocate a buffer on first use that persists until the LUN is
* destroyed.
*/
uint8_t *write_buffer;
struct ctl_devid *lun_devid;
TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists;
+1 -1
View File
@@ -53,7 +53,7 @@
TYPE="FreeBSD"
REVISION="13.4"
BRANCH="PRERELEASE"
BRANCH="RELEASE"
if [ -n "${BRANCH_OVERRIDE}" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
+13 -9
View File
@@ -986,6 +986,10 @@ nvpair_unpack_string_array(bool isbe __unused, nvpair_t *nvp,
for (ii = 0; ii < nvp->nvp_nitems; ii++) {
len = strnlen(tmp, size - 1) + 1;
size -= len;
if (tmp[len - 1] != '\0') {
ERRNO_SET(EINVAL);
return (NULL);
}
if (size < 0) {
ERRNO_SET(EINVAL);
return (NULL);
@@ -997,7 +1001,7 @@ nvpair_unpack_string_array(bool isbe __unused, nvpair_t *nvp,
return (NULL);
}
value = nv_malloc(sizeof(*value) * nvp->nvp_nitems);
value = nv_calloc(nvp->nvp_nitems, sizeof(*value));
if (value == NULL)
return (NULL);
@@ -1090,7 +1094,7 @@ nvpair_unpack_nvlist_array(bool isbe __unused, nvpair_t *nvp,
return (NULL);
}
value = nv_malloc(nvp->nvp_nitems * sizeof(*value));
value = nv_calloc(nvp->nvp_nitems, sizeof(*value));
if (value == NULL)
return (NULL);
@@ -1328,10 +1332,10 @@ nvpair_create_bool_array(const char *name, const bool *value, size_t nitems)
return (NULL);
}
size = sizeof(value[0]) * nitems;
data = nv_malloc(size);
data = nv_calloc(nitems, sizeof(value[0]));
if (data == NULL)
return (NULL);
size = sizeof(value[0]) * nitems;
memcpy(data, value, size);
nvp = nvpair_allocv(name, NV_TYPE_BOOL_ARRAY, (uint64_t)(uintptr_t)data,
@@ -1358,10 +1362,10 @@ nvpair_create_number_array(const char *name, const uint64_t *value,
return (NULL);
}
size = sizeof(value[0]) * nitems;
data = nv_malloc(size);
data = nv_calloc(nitems, sizeof(value[0]));
if (data == NULL)
return (NULL);
size = sizeof(value[0]) * nitems;
memcpy(data, value, size);
nvp = nvpair_allocv(name, NV_TYPE_NUMBER_ARRAY,
@@ -1391,7 +1395,7 @@ nvpair_create_string_array(const char *name, const char * const *value,
nvp = NULL;
datasize = 0;
data = nv_malloc(sizeof(value[0]) * nitems);
data = nv_calloc(nitems, sizeof(value[0]));
if (data == NULL)
return (NULL);
@@ -1438,7 +1442,7 @@ nvpair_create_nvlist_array(const char *name, const nvlist_t * const *value,
return (NULL);
}
nvls = nv_malloc(sizeof(value[0]) * nitems);
nvls = nv_calloc(nitems, sizeof(value[0]));
if (nvls == NULL)
return (NULL);
@@ -1505,7 +1509,7 @@ nvpair_create_descriptor_array(const char *name, const int *value,
nvp = NULL;
fds = nv_malloc(sizeof(value[0]) * nitems);
fds = nv_calloc(nitems, sizeof(value[0]));
if (fds == NULL)
return (NULL);
for (ii = 0; ii < nitems; ii++) {
+6 -2
View File
@@ -758,7 +758,7 @@ nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp)
int *fds;
nitems = nvlist_ndescriptors(nvl);
fds = nv_malloc(sizeof(fds[0]) * (nitems + 1));
fds = nv_calloc(nitems + 1, sizeof(fds[0]));
if (fds == NULL)
return (NULL);
if (nitems > 0)
@@ -1029,6 +1029,10 @@ static bool
nvlist_check_header(struct nvlist_header *nvlhdrp)
{
if (nvlhdrp->nvlh_size > SIZE_MAX - sizeof(nvlhdrp)) {
ERRNO_SET(EINVAL);
return (false);
}
if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) {
ERRNO_SET(EINVAL);
return (false);
@@ -1302,7 +1306,7 @@ nvlist_recv(int sock, int flags)
goto out;
if (nfds > 0) {
fds = nv_malloc(nfds * sizeof(fds[0]));
fds = nv_calloc(nfds, sizeof(fds[0]));
if (fds == NULL)
goto out;
if (fd_recv(sock, fds, nfds) == -1)
+7
View File
@@ -61,6 +61,7 @@
#define PCI_DEVICE_ID_AMD_17H_M60H_ROOT 0x1630
#define PCI_DEVICE_ID_AMD_19H_M10H_ROOT 0x14a4
#define PCI_DEVICE_ID_AMD_19H_M60H_ROOT 0x14d8
#define PCI_DEVICE_ID_AMD_19H_M70H_ROOT 0x14e8
struct pciid;
struct amdsmn_softc {
@@ -116,6 +117,12 @@ static const struct pciid {
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
.amdsmn_data_reg = F17H_SMN_DATA_REG,
},
{
.amdsmn_vendorid = CPU_VENDOR_AMD,
.amdsmn_deviceid = PCI_DEVICE_ID_AMD_19H_M70H_ROOT,
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
.amdsmn_data_reg = F17H_SMN_DATA_REG,
},
};
/*
+3
View File
@@ -116,6 +116,7 @@ struct amdtemp_softc {
#define DEVICEID_AMD_HOSTB17H_M60H_ROOT 0x1630
#define DEVICEID_AMD_HOSTB19H_M10H_ROOT 0x14a4
#define DEVICEID_AMD_HOSTB19H_M60H_ROOT 0x14d8
#define DEVICEID_AMD_HOSTB19H_M70H_ROOT 0x14e8
static const struct amdtemp_product {
uint16_t amdtemp_vendorid;
@@ -142,6 +143,7 @@ static const struct amdtemp_product {
{ VENDORID_AMD, DEVICEID_AMD_HOSTB17H_M60H_ROOT, false },
{ VENDORID_AMD, DEVICEID_AMD_HOSTB19H_M10H_ROOT, false },
{ VENDORID_AMD, DEVICEID_AMD_HOSTB19H_M60H_ROOT, false },
{ VENDORID_AMD, DEVICEID_AMD_HOSTB19H_M70H_ROOT, false },
};
/*
@@ -875,6 +877,7 @@ amdtemp_probe_ccd_sensors19h(device_t dev, uint32_t model)
_Static_assert((int)NUM_CCDS >= 12, "");
break;
case 0x60 ... 0x6f: /* Zen4 Ryzen "Raphael" */
case 0x70 ... 0x7f: /* Zen4 Ryzen "Phoenix" */
sc->sc_temp_base = AMDTEMP_ZEN4_CCD_TMP_BASE;
maxreg = 8;
_Static_assert((int)NUM_CCDS >= 8, "");
+12 -13
View File
@@ -1025,29 +1025,28 @@ cxgbe_nm_tx(struct adapter *sc, struct sge_nm_txq *nm_txq,
nm_txq->pidx = 0;
}
if (npkt == 0 && npkt_remaining == 0) {
if (npkt + npkt_remaining == 0) {
/* All done. */
if (lazy_tx_credit_flush == 0) {
if (lazy_tx_credit_flush == 0 ||
NMIDXDIFF(nm_txq, equiqidx) >= nm_txq->sidx / 2) {
wr->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ |
F_FW_WR_EQUIQ);
nm_txq->equeqidx = nm_txq->pidx;
nm_txq->equiqidx = nm_txq->pidx;
} else if (NMIDXDIFF(nm_txq, equeqidx) >= 64) {
wr->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ);
nm_txq->equeqidx = nm_txq->pidx;
}
ring_nm_txq_db(sc, nm_txq);
return;
}
if (NMIDXDIFF(nm_txq, equiqidx) >= nm_txq->sidx / 2) {
wr->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ |
F_FW_WR_EQUIQ);
nm_txq->equeqidx = nm_txq->pidx;
nm_txq->equiqidx = nm_txq->pidx;
} else if (NMIDXDIFF(nm_txq, equeqidx) >= 64) {
wr->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ);
nm_txq->equeqidx = nm_txq->pidx;
}
if (NMIDXDIFF(nm_txq, dbidx) >= 2 * SGE_MAX_WR_NDESC)
if (NMIDXDIFF(nm_txq, dbidx) >= 2 * SGE_MAX_WR_NDESC) {
if (NMIDXDIFF(nm_txq, equeqidx) >= 64) {
wr->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ);
nm_txq->equeqidx = nm_txq->pidx;
}
ring_nm_txq_db(sc, nm_txq);
}
}
/* Will get called again. */
+3 -1
View File
@@ -724,7 +724,9 @@ mountmsdosfs(struct vnode *odevvp, struct mount *mp)
}
}
clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv ;
clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv;
if (clusters >= (CLUST_RSRVD & pmp->pm_fatmask))
clusters = CLUST_RSRVD & pmp->pm_fatmask;
if (pmp->pm_maxcluster >= clusters) {
#ifdef MSDOSFS_DEBUG
printf("Warning: number of clusters (%ld) exceeds FAT "
+1 -1
View File
@@ -585,7 +585,7 @@ ktrprocexec(struct proc *p)
PROC_LOCK_ASSERT(p, MA_OWNED);
kiop = p->p_ktrioparms;
if (kiop == NULL || priv_check_cred(kiop->cr, PRIV_DEBUG_DIFFCRED))
if (kiop == NULL || priv_check_cred(kiop->cr, PRIV_DEBUG_DIFFCRED) == 0)
return (NULL);
mtx_lock(&ktrace_mtx);
+92 -49
View File
@@ -4293,8 +4293,7 @@ __umtx_op_sem2_wake(struct thread *td, struct _umtx_op_args *uap,
#define USHM_OBJ_UMTX(o) \
((struct umtx_shm_obj_list *)(&(o)->umtx_data))
#define USHMF_REG_LINKED 0x0001
#define USHMF_OBJ_LINKED 0x0002
#define USHMF_LINKED 0x0001
struct umtx_shm_reg {
TAILQ_ENTRY(umtx_shm_reg) ushm_reg_link;
LIST_ENTRY(umtx_shm_reg) ushm_obj_link;
@@ -4335,8 +4334,17 @@ umtx_shm_reg_delfree_tq(void *context __unused, int pending __unused)
static struct task umtx_shm_reg_delfree_task =
TASK_INITIALIZER(0, umtx_shm_reg_delfree_tq, NULL);
static struct umtx_shm_reg *
umtx_shm_find_reg_locked(const struct umtx_key *key)
/*
* Returns 0 if a SHM with the passed key is found in the registry, in which
* case it is returned through 'oreg'. Otherwise, returns an error among ESRCH
* (no corresponding SHM; ESRCH was chosen for compatibility, ENOENT would have
* been preferable) or EOVERFLOW (there is a corresponding SHM, but reference
* count would overflow, so can't return it), in which case '*oreg' is left
* unchanged.
*/
static int
umtx_shm_find_reg_locked(const struct umtx_key *key,
struct umtx_shm_reg **const oreg)
{
struct umtx_shm_reg *reg;
struct umtx_shm_reg_head *reg_head;
@@ -4352,26 +4360,38 @@ umtx_shm_find_reg_locked(const struct umtx_key *key)
reg->ushm_key.info.shared.offset ==
key->info.shared.offset) {
KASSERT(reg->ushm_key.type == TYPE_SHM, ("TYPE_USHM"));
KASSERT(reg->ushm_refcnt > 0,
KASSERT(reg->ushm_refcnt != 0,
("reg %p refcnt 0 onlist", reg));
KASSERT((reg->ushm_flags & USHMF_REG_LINKED) != 0,
KASSERT((reg->ushm_flags & USHMF_LINKED) != 0,
("reg %p not linked", reg));
/*
* Don't let overflow happen, just deny a new reference
* (this is additional protection against some reference
* count leak, which is known not to be the case at the
* time of this writing).
*/
if (__predict_false(reg->ushm_refcnt == UINT_MAX))
return (EOVERFLOW);
reg->ushm_refcnt++;
return (reg);
*oreg = reg;
return (0);
}
}
return (NULL);
return (ESRCH);
}
static struct umtx_shm_reg *
umtx_shm_find_reg(const struct umtx_key *key)
/*
* Calls umtx_shm_find_reg_unlocked() under the 'umtx_shm_lock'.
*/
static int
umtx_shm_find_reg(const struct umtx_key *key, struct umtx_shm_reg **const oreg)
{
struct umtx_shm_reg *reg;
int error;
mtx_lock(&umtx_shm_lock);
reg = umtx_shm_find_reg_locked(key);
error = umtx_shm_find_reg_locked(key, oreg);
mtx_unlock(&umtx_shm_lock);
return (reg);
return (error);
}
static void
@@ -4385,42 +4405,49 @@ umtx_shm_free_reg(struct umtx_shm_reg *reg)
}
static bool
umtx_shm_unref_reg_locked(struct umtx_shm_reg *reg, bool force)
umtx_shm_unref_reg_locked(struct umtx_shm_reg *reg, bool linked_ref)
{
bool res;
mtx_assert(&umtx_shm_lock, MA_OWNED);
KASSERT(reg->ushm_refcnt > 0, ("ushm_reg %p refcnt 0", reg));
reg->ushm_refcnt--;
res = reg->ushm_refcnt == 0;
if (res || force) {
if ((reg->ushm_flags & USHMF_REG_LINKED) != 0) {
TAILQ_REMOVE(&umtx_shm_registry[reg->ushm_key.hash],
reg, ushm_reg_link);
reg->ushm_flags &= ~USHMF_REG_LINKED;
}
if ((reg->ushm_flags & USHMF_OBJ_LINKED) != 0) {
LIST_REMOVE(reg, ushm_obj_link);
reg->ushm_flags &= ~USHMF_OBJ_LINKED;
}
KASSERT(reg->ushm_refcnt != 0, ("ushm_reg %p refcnt 0", reg));
if (linked_ref) {
if ((reg->ushm_flags & USHMF_LINKED) == 0)
/*
* The reference tied to USHMF_LINKED has already been
* released concurrently.
*/
return (false);
TAILQ_REMOVE(&umtx_shm_registry[reg->ushm_key.hash], reg,
ushm_reg_link);
LIST_REMOVE(reg, ushm_obj_link);
reg->ushm_flags &= ~USHMF_LINKED;
}
return (res);
reg->ushm_refcnt--;
return (reg->ushm_refcnt == 0);
}
static void
umtx_shm_unref_reg(struct umtx_shm_reg *reg, bool force)
umtx_shm_unref_reg(struct umtx_shm_reg *reg, bool linked_ref)
{
vm_object_t object;
bool dofree;
if (force) {
if (linked_ref) {
/*
* Note: This may be executed multiple times on the same
* shared-memory VM object in presence of concurrent callers
* because 'umtx_shm_lock' is not held all along in umtx_shm()
* and here.
*/
object = reg->ushm_obj->shm_object;
VM_OBJECT_WLOCK(object);
vm_object_set_flag(object, OBJ_UMTXDEAD);
VM_OBJECT_WUNLOCK(object);
}
mtx_lock(&umtx_shm_lock);
dofree = umtx_shm_unref_reg_locked(reg, force);
dofree = umtx_shm_unref_reg_locked(reg, linked_ref);
mtx_unlock(&umtx_shm_lock);
if (dofree)
umtx_shm_free_reg(reg);
@@ -4464,16 +4491,22 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key,
struct ucred *cred;
int error;
reg = umtx_shm_find_reg(key);
if (reg != NULL) {
*res = reg;
return (0);
error = umtx_shm_find_reg(key, res);
if (error != ESRCH) {
/*
* Either no error occured, and '*res' was filled, or EOVERFLOW
* was returned, indicating a reference count limit, and we
* won't create a duplicate registration. In both cases, we are
* done.
*/
return (error);
}
/* No entry, we will create one. */
cred = td->td_ucred;
if (!chgumtxcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_UMTXP)))
return (ENOMEM);
reg = uma_zalloc(umtx_shm_reg_zone, M_WAITOK | M_ZERO);
reg->ushm_refcnt = 1;
bcopy(key, &reg->ushm_key, sizeof(*key));
reg->ushm_obj = shm_alloc(td->td_ucred, O_RDWR, false);
reg->ushm_cred = crhold(cred);
@@ -4483,18 +4516,32 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key,
return (error);
}
mtx_lock(&umtx_shm_lock);
reg1 = umtx_shm_find_reg_locked(key);
if (reg1 != NULL) {
/* Re-lookup as 'umtx_shm_lock' has been temporarily released. */
error = umtx_shm_find_reg_locked(key, &reg1);
switch (error) {
case 0:
mtx_unlock(&umtx_shm_lock);
umtx_shm_free_reg(reg);
*res = reg1;
return (0);
case ESRCH:
break;
default:
mtx_unlock(&umtx_shm_lock);
umtx_shm_free_reg(reg);
return (error);
}
reg->ushm_refcnt++;
TAILQ_INSERT_TAIL(&umtx_shm_registry[key->hash], reg, ushm_reg_link);
LIST_INSERT_HEAD(USHM_OBJ_UMTX(key->info.shared.object), reg,
ushm_obj_link);
reg->ushm_flags = USHMF_REG_LINKED | USHMF_OBJ_LINKED;
reg->ushm_flags = USHMF_LINKED;
/*
* This is one reference for the registry and the list of shared
* mutexes referenced by the VM object containing the lock pointer, and
* another for the caller, which it will free after use. So, one of
* these is tied to the presence of USHMF_LINKED.
*/
reg->ushm_refcnt = 2;
mtx_unlock(&umtx_shm_lock);
*res = reg;
return (0);
@@ -4553,13 +4600,9 @@ umtx_shm(struct thread *td, void *addr, u_int flags)
if (error != 0)
return (error);
KASSERT(key.shared == 1, ("non-shared key"));
if ((flags & UMTX_SHM_CREAT) != 0) {
error = umtx_shm_create_reg(td, &key, &reg);
} else {
reg = umtx_shm_find_reg(&key);
if (reg == NULL)
error = ESRCH;
}
error = (flags & UMTX_SHM_CREAT) != 0 ?
umtx_shm_create_reg(td, &key, &reg) :
umtx_shm_find_reg(&key, &reg);
umtx_key_release(&key);
if (error != 0)
return (error);
+3 -1
View File
@@ -901,8 +901,10 @@ pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio)
uio->uio_iov->iov_len -= size;
uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + size;
if (uio->uio_iov->iov_len == 0)
if (uio->uio_iov->iov_len == 0) {
uio->uio_iov++;
uio->uio_iovcnt--;
}
uio->uio_resid -= size;
uio->uio_offset += size;
return (0);
+1 -1
View File
@@ -146,7 +146,7 @@ acl_copyin(const void *user_acl, struct acl *kernel_acl, acl_type_t type)
error = copyin(user_acl, &old, sizeof(old));
if (error != 0)
break;
acl_copy_oldacl_into_acl(&old, kernel_acl);
error = acl_copy_oldacl_into_acl(&old, kernel_acl);
break;
default:
+3 -3
View File
@@ -330,8 +330,8 @@ struct pfi_dynaddr {
mtx_unlock(_s->lock); \
} while (0)
#else
#define PF_STATE_LOCK(s) mtx_lock(s->lock)
#define PF_STATE_UNLOCK(s) mtx_unlock(s->lock)
#define PF_STATE_LOCK(s) mtx_lock((s)->lock)
#define PF_STATE_UNLOCK(s) mtx_unlock((s)->lock)
#endif
#ifdef INVARIANTS
@@ -2224,7 +2224,7 @@ struct pf_krule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
struct pf_addr *, struct pf_addr *,
uint16_t, uint16_t, struct pf_kanchor_stackframe *);
struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct pf_addr *,
struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *, int, struct pf_addr *,
struct pf_addr *, u_int16_t, u_int16_t);
struct pf_state_key *pf_state_key_clone(struct pf_state_key *);
+17 -18
View File
@@ -746,21 +746,6 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_read *nc, struct sctp_queu
nc->do_not_ref_stcb = control->do_not_ref_stcb;
}
static void
sctp_reset_a_control(struct sctp_queued_to_read *control,
struct sctp_inpcb *inp, uint32_t tsn)
{
control->fsn_included = tsn;
if (control->on_read_q) {
/*
* We have to purge it from there, hopefully this will work
* :-)
*/
TAILQ_REMOVE(&inp->read_queue, control, next);
control->on_read_q = 0;
}
}
static int
sctp_handle_old_unordered_data(struct sctp_tcb *stcb,
struct sctp_association *asoc,
@@ -1922,7 +1907,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
SCTP_SNPRINTF(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", mid);
goto err_out;
} else {
if ((tsn == control->fsn_included + 1) &&
if ((control->first_frag_seen) &&
(tsn == control->fsn_included + 1) &&
(control->end_added == 0)) {
SCTP_SNPRINTF(msg, sizeof(msg),
"Illegal message sequence, missing end for MID: %8.8x",
@@ -5430,12 +5416,25 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
}
if (!TAILQ_EMPTY(&control->reasm)) {
/* This has to be old data, unordered */
KASSERT(!asoc->idata_supported,
("Reassembly queue not empty for I-DATA"));
KASSERT(!ordered,
("Reassembly queue not empty for ordered data"));
if (control->data) {
sctp_m_freem(control->data);
control->data = NULL;
}
sctp_reset_a_control(control, stcb->sctp_ep, cumtsn);
control->fsn_included = 0xffffffff;
control->first_frag_seen = 0;
control->last_frag_seen = 0;
if (control->on_read_q) {
/*
* We have to purge it from there, hopefully this
* will work :-)
*/
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
control->on_read_q = 0;
}
chk = TAILQ_FIRST(&control->reasm);
if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
+1 -1
View File
@@ -1448,6 +1448,7 @@ tcp_init(void)
tcp_fastopen_init();
V_tcp_msl = TCPTV_MSL;
arc4rand(&V_ts_offset_secret, sizeof(V_ts_offset_secret), 0);
/* Skip initialization of globals for non-default instances. */
if (!IS_DEFAULT_VNET(curvnet))
@@ -1481,7 +1482,6 @@ tcp_init(void)
/* Initialize the TCP logging data. */
tcp_log_init();
#endif
arc4rand(&V_ts_offset_secret, sizeof(V_ts_offset_secret), 0);
if (tcp_soreceive_stream) {
#ifdef INET
+3 -3
View File
@@ -1595,8 +1595,7 @@ check_release_defrouter(const struct rib_cmd_info *rc, void *_cbdata)
struct nhop_object *nh;
nh = rc->rc_nh_old;
if ((nh != NULL) && (nh->nh_flags & NHF_DEFAULT)) {
if (rc->rc_cmd == RTM_DELETE && (nh->nh_flags & NHF_DEFAULT) != 0) {
dr = defrouter_lookup(&nh->gw6_sa.sin6_addr, nh->nh_ifp);
if (dr != NULL) {
dr->installed = 0;
@@ -1608,9 +1607,10 @@ check_release_defrouter(const struct rib_cmd_info *rc, void *_cbdata)
void
nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, void *arg)
{
#ifdef ROUTE_MPATH
rib_decompose_notification(rc, check_release_defrouter, NULL);
if (rc->rc_cmd == RTM_DELETE && !NH_IS_NHGRP(rc->rc_nh_old))
check_release_defrouter(rc, NULL);
#else
check_release_defrouter(rc, NULL);
#endif
+124 -63
View File
@@ -311,6 +311,9 @@ static int pf_test_fragment(struct pf_krule **, int,
struct pfi_kkif *, struct mbuf *, void *,
struct pf_pdesc *, struct pf_krule **,
struct pf_kruleset **);
static int pf_state_key_addr_setup(struct pf_pdesc *, struct mbuf *,
int, struct pf_state_key_cmp *, int, struct pf_addr *,
int, struct pf_addr *, int);
static int pf_tcp_track_full(struct pf_kstate **,
struct pfi_kkif *, struct mbuf *, int,
struct pf_pdesc *, u_short *, int *);
@@ -324,8 +327,8 @@ static int pf_test_state_udp(struct pf_kstate **, int,
void *, struct pf_pdesc *);
int pf_icmp_state_lookup(struct pf_state_key_cmp *,
struct pf_pdesc *, struct pf_kstate **, struct mbuf *,
int, struct pfi_kkif *, u_int16_t, u_int16_t,
int, int *, int);
int, int, struct pfi_kkif *, u_int16_t, u_int16_t,
int, int *, int, int);
static int pf_test_state_icmp(struct pf_kstate **, int,
struct pfi_kkif *, struct mbuf *, int,
void *, struct pf_pdesc *, u_short *);
@@ -379,7 +382,7 @@ extern int pf_end_threads;
extern struct proc *pf_purge_proc;
VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]);
enum { PF_ICMP_MULTI_NONE, PF_ICMP_MULTI_SOLICITED, PF_ICMP_MULTI_LINK };
enum { PF_ICMP_MULTI_NONE, PF_ICMP_MULTI_LINK };
#define PACKET_UNDO_NAT(_m, _pd, _off, _s, _dir) \
do { \
@@ -1423,9 +1426,66 @@ pf_state_key_ctor(void *mem, int size, void *arg, int flags)
return (0);
}
static int
pf_state_key_addr_setup(struct pf_pdesc *pd, struct mbuf *m, int off,
struct pf_state_key_cmp *key, int sidx, struct pf_addr *saddr,
int didx, struct pf_addr *daddr, int multi)
{
#ifdef INET6
struct nd_neighbor_solicit nd;
struct pf_addr *target;
u_short action, reason;
if (pd->af == AF_INET || pd->proto != IPPROTO_ICMPV6)
goto copy;
switch (pd->hdr.icmp6.icmp6_type) {
case ND_NEIGHBOR_SOLICIT:
if (multi)
return (-1);
if (!pf_pull_hdr(m, off, &nd, sizeof(nd), &action, &reason, pd->af))
return (-1);
target = (struct pf_addr *)&nd.nd_ns_target;
daddr = target;
break;
case ND_NEIGHBOR_ADVERT:
if (multi)
return (-1);
if (!pf_pull_hdr(m, off, &nd, sizeof(nd), &action, &reason, pd->af))
return (-1);
target = (struct pf_addr *)&nd.nd_ns_target;
saddr = target;
if (IN6_IS_ADDR_MULTICAST(&pd->dst->v6)) {
key->addr[didx].addr32[0] = 0;
key->addr[didx].addr32[1] = 0;
key->addr[didx].addr32[2] = 0;
key->addr[didx].addr32[3] = 0;
daddr = NULL; /* overwritten */
}
break;
default:
if (multi == PF_ICMP_MULTI_LINK) {
key->addr[sidx].addr32[0] = IPV6_ADDR_INT32_MLL;
key->addr[sidx].addr32[1] = 0;
key->addr[sidx].addr32[2] = 0;
key->addr[sidx].addr32[3] = IPV6_ADDR_INT32_ONE;
saddr = NULL; /* overwritten */
}
}
copy:
#endif
if (saddr)
PF_ACPY(&key->addr[sidx], saddr, pd->af);
if (daddr)
PF_ACPY(&key->addr[didx], daddr, pd->af);
return (0);
}
struct pf_state_key *
pf_state_key_setup(struct pf_pdesc *pd, struct pf_addr *saddr,
struct pf_addr *daddr, u_int16_t sport, u_int16_t dport)
pf_state_key_setup(struct pf_pdesc *pd, struct mbuf *m, int off,
struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t sport,
u_int16_t dport)
{
struct pf_state_key *sk;
@@ -1433,8 +1493,12 @@ pf_state_key_setup(struct pf_pdesc *pd, struct pf_addr *saddr,
if (sk == NULL)
return (NULL);
PF_ACPY(&sk->addr[pd->sidx], saddr, pd->af);
PF_ACPY(&sk->addr[pd->didx], daddr, pd->af);
if (pf_state_key_addr_setup(pd, m, off, (struct pf_state_key_cmp *)sk,
pd->sidx, pd->src, pd->didx, pd->dst, 0)) {
uma_zfree(V_pf_state_key_z, sk);
return (NULL);
}
sk->port[pd->sidx] = sport;
sk->port[pd->didx] = dport;
sk->proto = pd->proto;
@@ -4589,7 +4653,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
if (nr == NULL) {
KASSERT((sk == NULL && nk == NULL), ("%s: nr %p sk %p, nk %p",
__func__, nr, sk, nk));
sk = pf_state_key_setup(pd, pd->src, pd->dst, sport, dport);
sk = pf_state_key_setup(pd, m, off, pd->src, pd->dst, sport, dport);
if (sk == NULL)
goto csfailed;
nk = sk;
@@ -6004,8 +6068,9 @@ pf_multihome_scan_asconf(struct mbuf *m, int start, int len,
int
pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd,
struct pf_kstate **state, struct mbuf *m, int direction, struct pfi_kkif *kif,
u_int16_t icmpid, u_int16_t type, int icmp_dir, int *iidx, int multi)
struct pf_kstate **state, struct mbuf *m, int off, int direction,
struct pfi_kkif *kif, u_int16_t icmpid, u_int16_t type, int icmp_dir,
int *iidx, int multi, int inner)
{
key->af = pd->af;
key->proto = pd->proto;
@@ -6018,31 +6083,19 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd,
key->port[pd->sidx] = type;
key->port[pd->didx] = icmpid;
}
if (pd->af == AF_INET6 && multi != PF_ICMP_MULTI_NONE) {
switch (multi) {
case PF_ICMP_MULTI_SOLICITED:
key->addr[pd->sidx].addr32[0] = IPV6_ADDR_INT32_MLL;
key->addr[pd->sidx].addr32[1] = 0;
key->addr[pd->sidx].addr32[2] = IPV6_ADDR_INT32_ONE;
key->addr[pd->sidx].addr32[3] = pd->src->addr32[3];
key->addr[pd->sidx].addr8[12] = 0xff;
break;
case PF_ICMP_MULTI_LINK:
key->addr[pd->sidx].addr32[0] = IPV6_ADDR_INT32_MLL;
key->addr[pd->sidx].addr32[1] = 0;
key->addr[pd->sidx].addr32[2] = 0;
key->addr[pd->sidx].addr32[3] = IPV6_ADDR_INT32_ONE;
break;
}
} else
PF_ACPY(&key->addr[pd->sidx], pd->src, key->af);
PF_ACPY(&key->addr[pd->didx], pd->dst, key->af);
if (pf_state_key_addr_setup(pd, m, off, key, pd->sidx, pd->src,
pd->didx, pd->dst, multi))
return (PF_DROP);
STATE_LOOKUP(kif, key, direction, *state, pd);
if ((*state)->state_flags & PFSTATE_SLOPPY)
return (-1);
/* Is this ICMP message flowing in right direction? */
if ((*state)->rule.ptr->type &&
(((*state)->direction == direction) ?
(((!inner && (*state)->direction == direction) ||
(inner && (*state)->direction != direction)) ?
PF_IN : PF_OUT) != icmp_dir) {
if (V_pf_status.debug >= PF_DEBUG_MISC) {
printf("pf: icmp type %d in wrong direction (%d): ",
@@ -6050,6 +6103,8 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd,
pf_print_state(*state);
printf("\n");
}
PF_STATE_UNLOCK(*state);
*state = NULL;
return (PF_DROP);
}
return (-1);
@@ -6098,19 +6153,20 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
* ICMP query/reply message not related to a TCP/UDP packet.
* Search for an ICMP state.
*/
ret = pf_icmp_state_lookup(&key, pd, state, m, pd->dir,
ret = pf_icmp_state_lookup(&key, pd, state, m, off, pd->dir,
kif, virtual_id, virtual_type, icmp_dir, &iidx,
PF_ICMP_MULTI_NONE);
PF_ICMP_MULTI_NONE, 0);
if (ret >= 0) {
MPASS(*state == NULL);
if (ret == PF_DROP && pd->af == AF_INET6 &&
icmp_dir == PF_OUT) {
if (*state != NULL)
PF_STATE_UNLOCK((*state));
ret = pf_icmp_state_lookup(&key, pd, state, m,
ret = pf_icmp_state_lookup(&key, pd, state, m, off,
pd->dir, kif, virtual_id, virtual_type,
icmp_dir, &iidx, multi);
if (ret >= 0)
icmp_dir, &iidx, multi, 0);
if (ret >= 0) {
MPASS(*state == NULL);
return (ret);
}
} else
return (ret);
}
@@ -6192,6 +6248,7 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
int off2 = 0;
pd2.af = pd->af;
pd2.dir = pd->dir;
/* Payload packet is from the opposite direction. */
pd2.sidx = (direction == PF_IN) ? 1 : 0;
pd2.didx = (direction == PF_IN) ? 0 : 1;
@@ -6499,9 +6556,9 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
}
#ifdef INET
case IPPROTO_ICMP: {
struct icmp iih;
struct icmp *iih = &pd2.hdr.icmp;
if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
if (!pf_pull_hdr(m, off2, iih, ICMP_MINLEN,
NULL, reason, pd2.af)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: ICMP error message too short i"
@@ -6509,15 +6566,17 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
return (PF_DROP);
}
icmpid = iih.icmp_id;
pf_icmp_mapping(&pd2, iih.icmp_type,
icmpid = iih->icmp_id;
pf_icmp_mapping(&pd2, iih->icmp_type,
&icmp_dir, &multi, &virtual_id, &virtual_type);
ret = pf_icmp_state_lookup(&key, &pd2, state, m,
pd->dir, kif, virtual_id, virtual_type,
icmp_dir, &iidx, PF_ICMP_MULTI_NONE);
if (ret >= 0)
ret = pf_icmp_state_lookup(&key, &pd2, state, m, off,
pd2.dir, kif, virtual_id, virtual_type,
icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1);
if (ret >= 0) {
MPASS(*state == NULL);
return (ret);
}
/* translate source/destination address, if necessary */
if ((*state)->key[PF_SK_WIRE] !=
@@ -6528,10 +6587,10 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
(virtual_type == htons(ICMP_ECHO) &&
nk->port[iidx] != iih.icmp_id))
nk->port[iidx] != iih->icmp_id))
pf_change_icmp(pd2.src,
(virtual_type == htons(ICMP_ECHO)) ?
&iih.icmp_id : NULL,
&iih->icmp_id : NULL,
daddr, &nk->addr[pd2.sidx],
(virtual_type == htons(ICMP_ECHO)) ?
nk->port[iidx] : 0, NULL,
@@ -6547,7 +6606,7 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
m_copyback(m, off, ICMP_MINLEN, (caddr_t)&pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih);
m_copyback(m, off2, ICMP_MINLEN, (caddr_t)iih);
}
return (PF_PASS);
break;
@@ -6555,9 +6614,9 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
#endif /* INET */
#ifdef INET6
case IPPROTO_ICMPV6: {
struct icmp6_hdr iih;
struct icmp6_hdr *iih = &pd2.hdr.icmp6;
if (!pf_pull_hdr(m, off2, &iih,
if (!pf_pull_hdr(m, off2, iih,
sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: ICMP error message too short "
@@ -6565,22 +6624,24 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
return (PF_DROP);
}
pf_icmp_mapping(&pd2, iih.icmp6_type,
pf_icmp_mapping(&pd2, iih->icmp6_type,
&icmp_dir, &multi, &virtual_id, &virtual_type);
ret = pf_icmp_state_lookup(&key, &pd2, state, m,
ret = pf_icmp_state_lookup(&key, &pd2, state, m, off,
pd->dir, kif, virtual_id, virtual_type,
icmp_dir, &iidx, PF_ICMP_MULTI_NONE);
icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1);
if (ret >= 0) {
if (ret == PF_DROP && pd->af == AF_INET6 &&
MPASS(*state == NULL);
if (ret == PF_DROP && pd2.af == AF_INET6 &&
icmp_dir == PF_OUT) {
if (*state != NULL)
PF_STATE_UNLOCK((*state));
ret = pf_icmp_state_lookup(&key, pd,
state, m, pd->dir, kif,
ret = pf_icmp_state_lookup(&key, &pd2,
state, m, off, pd->dir, kif,
virtual_id, virtual_type,
icmp_dir, &iidx, multi);
if (ret >= 0)
icmp_dir, &iidx, multi, 1);
if (ret >= 0) {
MPASS(*state == NULL);
return (ret);
}
} else
return (ret);
}
@@ -6594,10 +6655,10 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
((virtual_type == htons(ICMP6_ECHO_REQUEST)) &&
nk->port[pd2.sidx] != iih.icmp6_id))
nk->port[pd2.sidx] != iih->icmp6_id))
pf_change_icmp(pd2.src,
(virtual_type == htons(ICMP6_ECHO_REQUEST))
? &iih.icmp6_id : NULL,
? &iih->icmp6_id : NULL,
daddr, &nk->addr[pd2.sidx],
(virtual_type == htons(ICMP6_ECHO_REQUEST))
? nk->port[iidx] : 0, NULL,
@@ -6615,7 +6676,7 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif
(caddr_t)&pd->hdr.icmp6);
m_copyback(m, ipoff2, sizeof(h2_6), (caddr_t)&h2_6);
m_copyback(m, off2, sizeof(struct icmp6_hdr),
(caddr_t)&iih);
(caddr_t)iih);
}
return (PF_PASS);
break;
+1 -1
View File
@@ -606,7 +606,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
return (NULL);
}
*skp = pf_state_key_setup(pd, saddr, daddr, sport, dport);
*skp = pf_state_key_setup(pd, m, off, saddr, daddr, sport, dport);
if (*skp == NULL)
return (NULL);
*nkp = pf_state_key_clone(*skp);
+1 -1
View File
@@ -59,7 +59,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1303503 /* Master, propagated to newvers */
#define __FreeBSD_version 1304000 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
+67
View File
@@ -71,7 +71,74 @@ cve_2019_5598_cleanup()
pft_cleanup
}
atf_test_case "ttl_exceeded" "cleanup"
ttl_exceeded_head()
{
atf_set descr 'Test that we correctly translate TTL exceeded back'
atf_set require.user root
}
ttl_exceeded_body()
{
pft_init
epair_srv=$(vnet_mkepair)
epair_int=$(vnet_mkepair)
epair_cl=$(vnet_mkepair)
vnet_mkjail srv ${epair_srv}a
jexec srv ifconfig ${epair_srv}a 192.0.2.1/24 up
jexec srv route add default 192.0.2.2
vnet_mkjail int ${epair_srv}b ${epair_int}a
jexec int sysctl net.inet.ip.forwarding=1
jexec int ifconfig ${epair_srv}b 192.0.2.2/24 up
jexec int ifconfig ${epair_int}a 203.0.113.2/24 up
vnet_mkjail nat ${epair_int}b ${epair_cl}b
jexec nat ifconfig ${epair_int}b 203.0.113.1/24 up
jexec nat ifconfig ${epair_cl}b 198.51.100.2/24 up
jexec nat sysctl net.inet.ip.forwarding=1
jexec nat route add default 203.0.113.2
vnet_mkjail cl ${epair_cl}a
jexec cl ifconfig ${epair_cl}a 198.51.100.1/24 up
jexec cl route add default 198.51.100.2
jexec nat pfctl -e
pft_set_rules nat \
"nat on ${epair_int}b from 198.51.100.0/24 -> (${epair_int}b)" \
"block" \
"pass inet proto udp" \
"pass inet proto icmp icmp-type { echoreq }"
# Sanity checks
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 198.51.100.2
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 203.0.113.1
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 203.0.113.2
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 192.0.2.1
echo "UDP"
atf_check -s exit:0 -e ignore -o match:".*203.0.113.2.*" \
jexec cl traceroute 192.0.2.1
jexec nat pfctl -Fs
echo "ICMP"
atf_check -s exit:0 -e ignore -o match:".*203.0.113.2.*" \
jexec cl traceroute -I 192.0.2.1
}
ttl_exceeded_cleanup()
{
pft_cleanup
}
atf_init_test_cases()
{
atf_add_test_case "cve_2019_5598"
atf_add_test_case "ttl_exceeded"
}
+67
View File
@@ -83,7 +83,74 @@ zero_id_cleanup()
pft_cleanup
}
atf_test_case "ttl_exceeded" "cleanup"
ttl_exceeded_head()
{
atf_set descr 'Test that we correctly translate TTL exceeded back'
atf_set require.user root
}
ttl_exceeded_body()
{
pft_init
epair_srv=$(vnet_mkepair)
epair_int=$(vnet_mkepair)
epair_cl=$(vnet_mkepair)
vnet_mkjail srv ${epair_srv}a
jexec srv ifconfig ${epair_srv}a inet6 2001:db8:1::1/64 no_dad up
jexec srv route add -6 default 2001:db8:1::2
vnet_mkjail int ${epair_srv}b ${epair_int}a
jexec int sysctl net.inet6.ip6.forwarding=1
jexec int ifconfig ${epair_srv}b inet6 2001:db8:1::2/64 no_dad up
jexec int ifconfig ${epair_int}a inet6 2001:db8:2::2/64 no_dad up
vnet_mkjail nat ${epair_int}b ${epair_cl}b
jexec nat ifconfig ${epair_int}b inet6 2001:db8:2::1 no_dad up
jexec nat ifconfig ${epair_cl}b inet6 2001:db8:3::2/64 no_dad up
jexec nat sysctl net.inet6.ip6.forwarding=1
jexec nat route add -6 default 2001:db8:2::2
vnet_mkjail cl ${epair_cl}a
jexec cl ifconfig ${epair_cl}a inet6 2001:db8:3::1/64 no_dad up
jexec cl route add -6 default 2001:db8:3::2
jexec nat pfctl -e
pft_set_rules nat \
"nat on ${epair_int}b from 2001:db8:3::/64 -> (${epair_int}b:0)" \
"block" \
"pass inet6 proto udp" \
"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv, echoreq }"
# Sanity checks
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 2001:db8:3::2
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 2001:db8:2::1
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 2001:db8:2::2
atf_check -s exit:0 -o ignore \
jexec cl ping -c 1 2001:db8:1::1
echo "UDP"
atf_check -s exit:0 -e ignore -o match:".*2001:db8:2::2.*" \
jexec cl traceroute6 2001:db8:1::1
jexec nat pfctl -Fs
echo "ICMP"
atf_check -s exit:0 -e ignore -o match:".*2001:db8:2::2.*" \
jexec cl traceroute6 -I 2001:db8:1::1
}
ttl_exceeded_cleanup()
{
pft_cleanup
}
atf_init_test_cases()
{
atf_add_test_case "zero_id"
atf_add_test_case "ttl_exceeded"
}
+1 -1
View File
@@ -224,7 +224,7 @@ main(int argc, char *argv[])
lc = login_getpwclass(pw);
if (setusercontext(lc, pw, pw->pw_uid,
LOGIN_SETALL) != 0)
LOGIN_SETALL & ~LOGIN_SETLOGIN) != 0)
errx(1, "setusercontext");
setenv("HOME", pw->pw_dir, 1);
cal();
+2 -1
View File
@@ -382,7 +382,8 @@ follow(file_info_t *files, enum STYLE style, off_t off)
sb2.st_dev != file->st.st_dev ||
sb2.st_nlink == 0) {
show(file);
fclose(file->fp);
if (file->fp != NULL)
fclose(file->fp);
file->fp = ftmp;
memcpy(&file->st, &sb2,
sizeof(struct stat));
+7 -3
View File
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd April 12, 2007
.Dd August 18, 2024
.Dt ADDUSER.CONF 5
.Os
.Sh NAME
@@ -171,8 +171,12 @@ The default information to be held in the GECOS field of
.It Va uidstart
The default user ID setting.
This must be a number above 1000 and fewer than 65534.
.It Va Zflag
Do not attempt to create ZFS home dataset.
.It Va Zcreate
Set to
.Dq no
to prevent the creation of a ZFS home dataset if
.Va homeprefix
is a ZFS mountpoint.
.El
.Sh EXAMPLES
The following is an example
+8 -1
View File
@@ -474,7 +474,7 @@ get_homeperm() {
# so, enable ZFS home dataset creation.
#
get_zfs_home() {
local _prefix=
local _prefix= _tmp=
# check if zfs kernel module is loaded before attempting to run zfs to
# prevent loading the kernel module on systems that don't use ZFS
@@ -487,6 +487,13 @@ get_zfs_home() {
Zcreate="no"
return
fi
# Make sure that _prefix is not a subdirectory within a dataset. If it
# is, the containing dataset will be the same for it and its parent.
_tmp=$(${ZFSCMD} list -Ho name "$(dirname "${homeprefix}")" 2>/dev/null)
if [ "${_tmp}" = "${_prefix}" ]; then
Zcreate="no"
return
fi
zhome="${_prefix}/${username}"
}
+2 -2
View File
@@ -659,7 +659,7 @@ pci_xhci_init_ep(struct pci_xhci_dev_emu *dev, int epid)
devep = &dev->eps[epid];
pstreams = XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0);
if (pstreams > 0) {
DPRINTF(("init_ep %d with pstreams %d", epid, pstreams));
DPRINTF(("init_ep %d with pstreams %u", epid, pstreams));
assert(devep->ep_sctx_trbs == NULL);
devep->ep_sctx = XHCI_GADDR(dev->xsc, ep_ctx->qwEpCtx2 &
@@ -1201,7 +1201,7 @@ pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep,
}
/* only support primary stream */
if (streamid > devep->ep_MaxPStreams)
if (streamid >= devep->ep_MaxPStreams)
return (XHCI_TRB_ERROR_STREAM_TYPE);
sctx = (struct xhci_stream_ctx *)XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) +
+5 -1
View File
@@ -741,6 +741,9 @@ Secondly, it will only remove files and directories that are actually owned by
the user, or symbolic links owned by anyone under the user's home directory.
Finally, after deleting all contents owned by the user only empty directories
will be removed.
If the home directory is a ZFS dataset and has been emptied,
the dataset will be destroyed.
ZFS datasets within the home directory and snapshots are not handled.
If any additional cleanup work is required, this is left to the administrator.
.El
.Pp
@@ -1077,7 +1080,8 @@ No base home directory configured.
.Xr passwd 5 ,
.Xr pw.conf 5 ,
.Xr pwd_mkdb 8 ,
.Xr vipw 8
.Xr vipw 8 ,
.Xr zfs 8
.Sh HISTORY
The
.Nm
+10 -5
View File
@@ -28,7 +28,7 @@
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <ctype.h>
@@ -687,6 +687,7 @@ rmat(uid_t uid)
while ((e = readdir(d)) != NULL) {
struct stat st;
pid_t pid;
if (strncmp(e->d_name, ".lock", 5) != 0 &&
stat(e->d_name, &st) == 0 &&
@@ -697,11 +698,12 @@ rmat(uid_t uid)
e->d_name,
NULL
};
if (posix_spawn(NULL, argv[0], NULL, NULL,
if (posix_spawn(&pid, argv[0], NULL, NULL,
(char *const *) argv, environ)) {
warn("Failed to execute '%s %s'",
argv[0], argv[1]);
}
} else
(void) waitpid(pid, NULL, 0);
}
}
closedir(d);
@@ -971,11 +973,14 @@ pw_user_del(int argc, char **argv, char *arg1)
"-r",
NULL
};
if (posix_spawnp(NULL, argv[0], NULL, NULL,
pid_t pid;
if (posix_spawnp(&pid, argv[0], NULL, NULL,
(char *const *) argv, environ)) {
warn("Failed to execute '%s %s'",
argv[0], argv[1]);
}
} else
(void) waitpid(pid, NULL, 0);
}
}
+1 -1
View File
@@ -140,7 +140,7 @@ void vendgrent(void);
void copymkdir(int rootfd, char const * dir, int skelfd, mode_t mode, uid_t uid,
gid_t gid, int flags);
void rm_r(int rootfd, char const * dir, uid_t uid);
bool rm_r(int rootfd, char const * dir, uid_t uid);
__END_DECLS
#endif /* !_PWUPD_H */
+102 -11
View File
@@ -26,35 +26,58 @@
* SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <libutil.h>
#include <spawn.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pwupd.h"
void
static bool try_dataset_remove(const char *home);
extern char **environ;
/*
* "rm -r" a directory tree. If the top-level directory cannot be removed
* due to EBUSY, indicating that it is a ZFS dataset, and we have emptied
* it, destroy the dataset. Return true if any files or directories
* remain.
*/
bool
rm_r(int rootfd, const char *path, uid_t uid)
{
int dirfd;
DIR *d;
struct dirent *e;
struct stat st;
const char *fullpath;
bool skipped = false;
fullpath = path;
if (*path == '/')
path++;
dirfd = openat(rootfd, path, O_DIRECTORY);
if (dirfd == -1) {
return;
return (true);
}
d = fdopendir(dirfd);
if (d == NULL) {
(void)close(dirfd);
return;
return (true);
}
while ((e = readdir(d)) != NULL) {
if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0)
@@ -62,16 +85,84 @@ rm_r(int rootfd, const char *path, uid_t uid)
if (fstatat(dirfd, e->d_name, &st, AT_SYMLINK_NOFOLLOW) != 0)
continue;
if (S_ISDIR(st.st_mode))
rm_r(dirfd, e->d_name, uid);
else if (S_ISLNK(st.st_mode) || st.st_uid == uid)
if (S_ISDIR(st.st_mode)) {
if (rm_r(dirfd, e->d_name, uid) == true)
skipped = true;
} else if (S_ISLNK(st.st_mode) || st.st_uid == uid)
unlinkat(dirfd, e->d_name, 0);
else
skipped = true;
}
closedir(d);
if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) != 0)
return;
if (S_ISLNK(st.st_mode))
unlinkat(rootfd, path, 0);
else if (st.st_uid == uid)
unlinkat(rootfd, path, AT_REMOVEDIR);
return (skipped);
if (S_ISLNK(st.st_mode)) {
if (unlinkat(rootfd, path, 0) == -1)
skipped = true;
} else if (st.st_uid == uid) {
if (unlinkat(rootfd, path, AT_REMOVEDIR) == -1) {
if (errno == EBUSY && skipped == false)
skipped = try_dataset_remove(fullpath);
else
skipped = true;
}
} else
skipped = true;
return (skipped);
}
/*
* If the home directory is a ZFS dataset, attempt to destroy it.
* Return true if the dataset is not destroyed.
* This would be more straightforward as a shell script.
*/
static bool
try_dataset_remove(const char *path)
{
bool skipped = true;
struct statfs stat;
const char *argv[] = {
"/sbin/zfs",
"destroy",
NULL,
NULL
};
int status;
pid_t pid;
/* see if this is an absolute path (top-level directory) */
if (*path != '/')
return (skipped);
/* see if ZFS is loaded */
if (kld_isloaded("zfs") == 0)
return (skipped);
/* This won't work if root dir is not / (-R option) */
if (strcmp(conf.rootdir, "/") != 0) {
warnx("cannot destroy home dataset when -R was used");
return (skipped);
}
/* if so, find dataset name */
if (statfs(path, &stat) != 0) {
warn("statfs %s", path);
return (skipped);
}
/*
* Check that the path refers to the dataset itself,
* not a subdirectory.
*/
if (strcmp(stat.f_mntonname, path) != 0)
return (skipped);
argv[2] = stat.f_mntfromname;
if ((skipped = posix_spawn(&pid, argv[0], NULL, NULL,
(char *const *) argv, environ)) != 0) {
warn("Failed to execute '%s %s %s'",
argv[0], argv[1], argv[2]);
} else {
if (waitpid(pid, &status, 0) != -1 && status != 0) {
warnx("'%s %s %s' exit status %d\n",
argv[0], argv[1], argv[2], status);
}
}
return (skipped);
}