aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.inc139
-rw-r--r--UPDATING4
-rw-r--r--contrib/libarchive/NEWS2
-rw-r--r--contrib/libarchive/SECURITY.md2
-rwxr-xr-xcontrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh3
-rw-r--r--contrib/libarchive/cat/bsdcat.c15
-rw-r--r--contrib/libarchive/cat/cmdline.c2
-rw-r--r--contrib/libarchive/cpio/cmdline.c2
-rw-r--r--contrib/libarchive/cpio/cpio.c14
-rw-r--r--contrib/libarchive/cpio/test/test_owner_parse.c2
-rw-r--r--contrib/libarchive/libarchive/archive.h4
-rw-r--r--contrib/libarchive/libarchive/archive_acl.c23
-rw-r--r--contrib/libarchive/libarchive/archive_check_magic.c9
-rw-r--r--contrib/libarchive/libarchive/archive_cryptor.c8
-rw-r--r--contrib/libarchive/libarchive/archive_cryptor_private.h11
-rw-r--r--contrib/libarchive/libarchive/archive_entry.h2
-rw-r--r--contrib/libarchive/libarchive/archive_entry_paths.32
-rw-r--r--contrib/libarchive/libarchive/archive_entry_stat.c6
-rw-r--r--contrib/libarchive/libarchive/archive_parse_date.c4
-rw-r--r--contrib/libarchive/libarchive/archive_platform.h10
-rw-r--r--contrib/libarchive/libarchive/archive_platform_stat.h45
-rw-r--r--contrib/libarchive/libarchive/archive_private.h1
-rw-r--r--contrib/libarchive/libarchive/archive_read.c7
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c12
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk_posix.c157
-rw-r--r--contrib/libarchive/libarchive/archive_read_open_fd.c23
-rw-r--r--contrib/libarchive/libarchive/archive_read_open_file.c16
-rw-r--r--contrib/libarchive/libarchive/archive_read_open_filename.c31
-rw-r--r--contrib/libarchive/libarchive/archive_read_set_format.c32
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_filter_program.c7
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_7zip.c7
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_mtree.c23
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_rar.c8
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_rar5.c66
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_tar.c70
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_warc.c2
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_xar.c2
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_zip.c4
-rw-r--r--contrib/libarchive/libarchive/archive_string.c5
-rw-r--r--contrib/libarchive/libarchive/archive_string_sprintf.c2
-rw-r--r--contrib/libarchive/libarchive/archive_util.c38
-rw-r--r--contrib/libarchive/libarchive/archive_write.c30
-rw-r--r--contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c4
-rw-r--r--contrib/libarchive/libarchive/archive_write_add_filter_gzip.c55
-rw-r--r--contrib/libarchive/libarchive/archive_write_add_filter_program.c11
-rw-r--r--contrib/libarchive/libarchive/archive_write_add_filter_zstd.c2
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk_posix.c16
-rw-r--r--contrib/libarchive/libarchive/archive_write_open_fd.c2
-rw-r--r--contrib/libarchive/libarchive/archive_write_open_file.c14
-rw-r--r--contrib/libarchive/libarchive/archive_write_open_filename.c3
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_7zip.c2
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_mtree.c19
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_xar.c6
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_zip.c25
-rw-r--r--contrib/libarchive/libarchive/filter_fork_posix.c37
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_nfs4.c7
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_posix1e.c5
-rw-r--r--contrib/libarchive/libarchive/test/test_archive_parse_date.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_archive_string_conversion.c10
-rw-r--r--contrib/libarchive/libarchive/test/test_entry.c11
-rw-r--r--contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c4
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_7zip.c81
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_rar5.c66
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu6
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu6
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu7
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu6
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c48
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu20
-rw-r--r--contrib/libarchive/libarchive/test/test_read_set_format.c7
-rw-r--r--contrib/libarchive/libarchive/test/test_write_filter_bzip2.c29
-rw-r--r--contrib/libarchive/libarchive/test/test_write_filter_gzip.c12
-rw-r--r--contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c7
-rw-r--r--contrib/libarchive/libarchive_fe/lafe_err.c (renamed from contrib/libarchive/libarchive_fe/err.c)2
-rw-r--r--contrib/libarchive/libarchive_fe/lafe_err.h (renamed from contrib/libarchive/libarchive_fe/err.h)0
-rw-r--r--contrib/libarchive/libarchive_fe/line_reader.c2
-rw-r--r--contrib/libarchive/libarchive_fe/passphrase.c2
-rw-r--r--contrib/libarchive/tar/bsdtar.c7
-rw-r--r--contrib/libarchive/tar/bsdtar.h8
-rw-r--r--contrib/libarchive/tar/cmdline.c2
-rw-r--r--contrib/libarchive/tar/creation_set.c2
-rw-r--r--contrib/libarchive/tar/read.c2
-rw-r--r--contrib/libarchive/tar/subst.c2
-rw-r--r--contrib/libarchive/tar/test/test_crlf_mtree.c74
-rw-r--r--contrib/libarchive/tar/test/test_option_safe_writes.c5
-rw-r--r--contrib/libarchive/tar/util.c7
-rw-r--r--contrib/libarchive/tar/write.c29
-rw-r--r--contrib/libarchive/test_utils/test_common.h10
-rw-r--r--contrib/libarchive/test_utils/test_main.c156
-rw-r--r--contrib/libarchive/unzip/bsdunzip.c15
-rw-r--r--contrib/libarchive/unzip/cmdline.c2
-rw-r--r--contrib/libarchive/unzip/test/test_C.c4
-rw-r--r--contrib/libarchive/unzip/test/test_L.c4
-rw-r--r--contrib/libarchive/unzip/test/test_P_encryption.c12
-rw-r--r--contrib/libarchive/unzip/test/test_basic.c4
-rw-r--r--contrib/libarchive/unzip/test/test_d.c8
-rw-r--r--contrib/libarchive/unzip/test/test_doubledash.c4
-rw-r--r--contrib/libarchive/unzip/test/test_glob.c4
-rw-r--r--contrib/libarchive/unzip/test/test_j.c4
-rw-r--r--contrib/libarchive/unzip/test/test_n.c4
-rw-r--r--contrib/libarchive/unzip/test/test_o.c4
-rw-r--r--contrib/libarchive/unzip/test/test_p.c4
-rw-r--r--contrib/libarchive/unzip/test/test_q.c4
-rw-r--r--contrib/libarchive/unzip/test/test_singlefile.c4
-rw-r--r--contrib/libarchive/unzip/test/test_t.c4
-rw-r--r--contrib/libarchive/unzip/test/test_x.c12
-rw-r--r--etc/mtree/BSD.include.dist2
-rw-r--r--etc/mtree/BSD.tests.dist2
-rw-r--r--include/stdckdint.h6
-rw-r--r--krb5/include/autoconf.h8
-rw-r--r--lib/libarchive/tests/Makefile6
-rw-r--r--lib/libc/inet/inet_net_ntop.c206
-rw-r--r--lib/libc/inet/inet_net_pton.c363
-rw-r--r--lib/libc/tests/net/Makefile2
-rw-r--r--lib/libc/tests/net/inet_net_test.cc333
-rw-r--r--lib/libsys/kqueue.229
-rw-r--r--lib/libutil/mntopts.c53
-rw-r--r--libexec/rc/rc.conf3
-rwxr-xr-xlibexec/rc/rc.d/dmesg2
-rwxr-xr-xlibexec/rc/rc.d/hostapd9
-rw-r--r--release/Makefile2
-rw-r--r--release/Makefile.oracle19
-rw-r--r--release/tools/vmimage.subr66
-rw-r--r--sbin/devd/snd.conf5
-rw-r--r--sbin/geom/core/geom.c37
-rw-r--r--share/man/man4/Makefile12
-rw-r--r--share/man/man4/aw_gpio.4 (renamed from share/man/man4/man4.arm/aw_gpio.4)2
-rw-r--r--share/man/man4/aw_mmc.4 (renamed from share/man/man4/man4.arm/aw_mmc.4)6
-rw-r--r--share/man/man4/aw_rtc.4 (renamed from share/man/man4/man4.arm/aw_rtc.4)2
-rw-r--r--share/man/man4/aw_sid.4 (renamed from share/man/man4/man4.arm/aw_sid.4)2
-rw-r--r--share/man/man4/aw_spi.4 (renamed from share/man/man4/man4.arm/aw_spi.4)2
-rw-r--r--share/man/man4/aw_syscon.4 (renamed from share/man/man4/man4.arm/aw_syscon.4)2
-rw-r--r--share/man/man4/man4.aarch64/Makefile6
-rw-r--r--share/man/man4/man4.arm/Makefile6
-rw-r--r--share/man/man4/snd_dummy.417
-rw-r--r--share/man/man5/src.conf.56
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--share/man/man9/VOP_OPENCLOSE.913
-rw-r--r--share/man/man9/uio.914
-rw-r--r--share/misc/bsd-family-tree3
-rw-r--r--share/misc/committers-src.dot2
-rw-r--r--share/mk/src.opts.mk2
-rw-r--r--sys/amd64/pt/pt.c221
-rw-r--r--sys/amd64/sgx/sgx_linux.c11
-rw-r--r--sys/amd64/vmm/vmm.c3
-rw-r--r--sys/amd64/vmm/vmm_dev_machdep.c255
-rw-r--r--sys/arm/arm/elf_machdep.c4
-rw-r--r--sys/arm/conf/GENERIC4
-rw-r--r--sys/arm/conf/NOTES5
-rw-r--r--sys/arm/include/ieeefp.h10
-rw-r--r--sys/arm/ti/clk/ti_clkctrl.c6
-rw-r--r--sys/arm/ti/ti_pruss.c1
-rw-r--r--sys/arm64/arm64/elf32_machdep.c2
-rw-r--r--sys/arm64/vmm/vmm.c5
-rw-r--r--sys/arm64/vmm/vmm_dev_machdep.c43
-rw-r--r--sys/cam/scsi/scsi_pass.c3
-rw-r--r--sys/cam/scsi/scsi_target.c1
-rw-r--r--sys/compat/linux/linux_event.c2
-rw-r--r--sys/compat/linux/linux_ioctl.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/bitops.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compiler.h8
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/etherdevice.h23
-rw-r--r--sys/compat/linuxkpi/common/include/linux/fips.h12
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ieee80211.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/netdevice.h15
-rw-r--r--sys/compat/linuxkpi/common/include/linux/nl80211.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/pci.h13
-rw-r--r--sys/compat/linuxkpi/common/include/linux/platform_device.h2
-rw-r--r--sys/compat/linuxkpi/common/include/linux/skbuff.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h47
-rw-r--r--sys/compat/linuxkpi/common/include/net/cfg80211.h320
-rw-r--r--sys/compat/linuxkpi/common/include/net/mac80211.h37
-rw-r--r--sys/compat/linuxkpi/common/include/net/netmem.h21
-rw-r--r--sys/compat/linuxkpi/common/include/net/page_pool.h119
-rw-r--r--sys/compat/linuxkpi/common/include/net/page_pool/helpers.h79
-rw-r--r--sys/compat/linuxkpi/common/include/net/page_pool/types.h36
-rw-r--r--sys/compat/linuxkpi/common/src/linux_80211.c12
-rw-r--r--sys/compat/linuxkpi/common/src/linux_80211_macops.c2
-rw-r--r--sys/compat/linuxkpi/common/src/linux_compat.c2
-rw-r--r--sys/conf/dtb.build.mk9
-rw-r--r--sys/conf/files.x861
-rwxr-xr-xsys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh11
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-qemu.yml2
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c185
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_vdev.c64
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/uio.h1
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_status.c78
-rw-r--r--sys/contrib/openzfs/lib/libzpool/kernel.c79
-rw-r--r--sys/contrib/openzfs/man/man8/zdb.814
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c3
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c31
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c1
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c77
-rw-r--r--sys/contrib/openzfs/module/zfs/arc.c16
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_seek.c35
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos.ksh2
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/zvol/zvol_misc/zvol_misc_trim.ksh7
-rw-r--r--sys/dev/aac/aac_linux.c10
-rw-r--r--sys/dev/aacraid/aacraid_linux.c10
-rw-r--r--sys/dev/ahci/ahciem.c2
-rw-r--r--sys/dev/atkbdc/psm.c1
-rw-r--r--sys/dev/cyapa/cyapa.c3
-rw-r--r--sys/dev/evdev/cdev.c1
-rw-r--r--sys/dev/evdev/uinput.c1
-rw-r--r--sys/dev/gpio/gpioc.c3
-rw-r--r--sys/dev/hid/hidraw.c1
-rw-r--r--sys/dev/hid/u2f.c1
-rw-r--r--sys/dev/iommu/busdma_iommu.c7
-rw-r--r--sys/dev/ipmi/ipmi_linux.c10
-rw-r--r--sys/dev/mfi/mfi_linux.c10
-rw-r--r--sys/dev/mrsas/mrsas_linux.c10
-rw-r--r--sys/dev/netmap/netmap_freebsd.c17
-rw-r--r--sys/dev/null/null.c6
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c24
-rw-r--r--sys/dev/nvme/nvme_ns.c5
-rw-r--r--sys/dev/nvme/nvme_private.h1
-rw-r--r--sys/dev/qat/qat_common/adf_freebsd_dev_processes.c1
-rw-r--r--sys/dev/random/fenestrasX/fx_pool.c3
-rw-r--r--sys/dev/random/ivy.c69
-rw-r--r--sys/dev/random/random_harvestq.c4
-rw-r--r--sys/dev/random/rdseed.c169
-rw-r--r--sys/dev/sound/dummy.c6
-rw-r--r--sys/dev/sound/pci/hda/hdac.c1
-rw-r--r--sys/dev/sound/pci/hda/hdac.h1
-rw-r--r--sys/dev/sound/pcm/dsp.c18
-rw-r--r--sys/dev/tdfx/tdfx_linux.c2
-rw-r--r--sys/dev/tdfx/tdfx_linux.h12
-rw-r--r--sys/dev/usb/controller/ehci_pci.c7
-rw-r--r--sys/dev/usb/usb_dev.c2
-rw-r--r--sys/dev/vmm/vmm_dev.c23
-rw-r--r--sys/dev/vmm/vmm_dev.h1
-rw-r--r--sys/fs/cuse/cuse.c2
-rw-r--r--sys/fs/fuse/fuse_device.c2
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c23
-rw-r--r--sys/fs/nfs/nfs_var.h2
-rw-r--r--sys/geom/geom_dev.c1
-rw-r--r--sys/i386/i386/elf_machdep.c12
-rw-r--r--sys/i386/linux/linux_sysvec.c12
-rw-r--r--sys/kern/imgact_elf.c4
-rw-r--r--sys/kern/kern_descrip.c55
-rw-r--r--sys/kern/kern_devctl.c1
-rw-r--r--sys/kern/kern_event.c267
-rw-r--r--sys/kern/kern_fork.c2
-rw-r--r--sys/kern/kern_jail.c23
-rw-r--r--sys/kern/kern_jaildesc.c1
-rw-r--r--sys/kern/kern_sig.c1
-rw-r--r--sys/kern/subr_kdb.c2
-rw-r--r--sys/kern/subr_log.c1
-rw-r--r--sys/kern/sys_eventfd.c7
-rw-r--r--sys/kern/sys_pipe.c5
-rw-r--r--sys/kern/sys_procdesc.c1
-rw-r--r--sys/kern/tty.c2
-rw-r--r--sys/kern/tty_pts.c2
-rw-r--r--sys/kern/uipc_mqueue.c2
-rw-r--r--sys/kern/uipc_socket.c3
-rw-r--r--sys/kern/uipc_usrreq.c2
-rw-r--r--sys/kern/vfs_aio.c4
-rw-r--r--sys/kern/vfs_cluster.c4
-rw-r--r--sys/kern/vfs_inotify.c1
-rw-r--r--sys/kern/vfs_subr.c15
-rw-r--r--sys/modules/Makefile17
-rw-r--r--sys/modules/allwinner/aw_sid/Makefile3
-rw-r--r--sys/modules/allwinner/aw_thermal/Makefile3
-rw-r--r--sys/modules/dtb/allwinner/Makefile7
-rw-r--r--sys/modules/dtb/starfive/Makefile7
-rw-r--r--sys/modules/rdrand_rng/Makefile5
-rw-r--r--sys/modules/rdseed_rng/Makefile9
-rw-r--r--sys/modules/zfs/zfs_config.h4
-rw-r--r--sys/modules/zfs/zfs_gitrev.h2
-rw-r--r--sys/net/bpf.c2
-rw-r--r--sys/net/if_tuntap.c2
-rw-r--r--sys/net/if_vxlan.c4
-rw-r--r--sys/netinet/in_pcb.c13
-rw-r--r--sys/netinet/libalias/alias_db.c2
-rw-r--r--sys/netinet/tcp_stacks/bbr.c8
-rw-r--r--sys/netinet/tcp_stacks/rack.c83
-rw-r--r--sys/netinet/tcp_syncache.c2
-rw-r--r--sys/netinet/udp_usrreq.c15
-rw-r--r--sys/netpfil/pf/pf.c1
-rw-r--r--sys/netpfil/pf/pf_lb.c1
-rw-r--r--sys/powerpc/powerpc/elf32_machdep.c8
-rw-r--r--sys/powerpc/powerpc/elf64_machdep.c12
-rw-r--r--sys/riscv/conf/std.allwinner3
-rw-r--r--sys/riscv/conf/std.starfive3
-rw-r--r--sys/riscv/riscv/elf_machdep.c4
-rw-r--r--sys/riscv/vmm/vmm.c5
-rw-r--r--sys/riscv/vmm/vmm_dev_machdep.c37
-rw-r--r--sys/security/audit/audit_pipe.c1
-rw-r--r--sys/sys/ata.h3
-rw-r--r--sys/sys/event.h3
-rw-r--r--sys/sys/eventvar.h2
-rw-r--r--sys/sys/file.h4
-rw-r--r--sys/sys/filedesc.h2
-rw-r--r--sys/sys/imgact_elf.h6
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/random.h4
-rw-r--r--sys/sys/syscallsubr.h3
-rw-r--r--sys/x86/acpica/acpi_apm.c1
-rw-r--r--sys/x86/iommu/amd_intrmap.c9
-rw-r--r--tests/sys/geom/class/Makefile1
-rw-r--r--tests/sys/geom/class/label/Makefile7
-rwxr-xr-xtests/sys/geom/class/label/basic.sh59
-rw-r--r--tests/sys/netinet/so_reuseport_lb_test.c148
-rw-r--r--tests/sys/netpfil/pf/rdr.sh51
-rw-r--r--tests/sys/netpfil/pf/sctp.sh18
-rwxr-xr-xtools/test/stress2/misc/kevent17.sh176
-rwxr-xr-xtools/test/stress2/misc/kevent18.sh152
-rwxr-xr-xtools/test/stress2/misc/kevent19.sh187
-rwxr-xr-xtools/tools/git/mfc-candidates.lua8
-rw-r--r--usr.bin/bsdcat/Makefile2
-rw-r--r--usr.bin/cpio/Makefile2
-rw-r--r--usr.bin/cpio/tests/Makefile2
-rw-r--r--usr.bin/find/find.c2
-rw-r--r--usr.bin/mkimg/mkimg.c21
-rw-r--r--usr.bin/ncurses/Makefile2
-rw-r--r--usr.bin/sockstat/main.c4
-rw-r--r--usr.bin/tar/Makefile3
-rw-r--r--usr.bin/tar/tests/Makefile1
-rw-r--r--usr.bin/unzip/Makefile2
-rw-r--r--usr.bin/unzip/tests/Makefile2
-rw-r--r--usr.sbin/bsdinstall/Makefile3
-rwxr-xr-xusr.sbin/bsdinstall/scripts/auto2
-rwxr-xr-xusr.sbin/bsdinstall/scripts/bootconfig2
-rwxr-xr-xusr.sbin/bsdinstall/scripts/jail4
-rwxr-xr-xusr.sbin/bsdinstall/scripts/keymap2
-rwxr-xr-xusr.sbin/bsdinstall/scripts/script2
-rwxr-xr-xusr.sbin/bsdinstall/scripts/zfsboot2
-rw-r--r--usr.sbin/pmcstat/pmcpl_callgraph.c2
-rw-r--r--usr.sbin/quot/quot.c27
-rw-r--r--usr.sbin/sndctl/sndctl.c4
-rw-r--r--usr.sbin/virtual_oss/virtual_bt_speaker/bt_speaker.c1
-rw-r--r--usr.sbin/virtual_oss/virtual_oss/int.h3
-rw-r--r--usr.sbin/virtual_oss/virtual_oss/main.c1
-rw-r--r--usr.sbin/virtual_oss/virtual_oss/utils.h31
335 files changed, 4871 insertions, 2186 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index a86dead09aa1..e341599ac505 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -587,7 +587,16 @@ PKG_VERSION:= ${_PKG_REVISION}${EXTRA_REVISION:C/[[:space:]]//g}
.endif # !defined(_MKSHOWCONFIG)
+PKG_NAME_PREFIX?= FreeBSD
+PKG_MAINTAINER?= re@FreeBSD.org
+PKG_WWW?= https://www.FreeBSD.org
+PKG_WORKERS_COUNT?= 1
+
.if make(*package*)
+.export PKG_NAME_PREFIX
+.export PKG_MAINTAINER
+.export PKG_WWW
+
.if !defined(PKG_TIMESTAMP)
.if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
SOURCE_DATE_EPOCH!= ${GIT_CMD} -C ${SRCDIR} show -s --format=%ct HEAD
@@ -598,14 +607,6 @@ SOURCE_DATE_EPOCH= ${TIMEEPOCHNOW:gmtime}
.else
SOURCE_DATE_EPOCH= ${PKG_TIMESTAMP}
.endif
-PKG_WORKERS_COUNT?= 1
-
-PKG_NAME_PREFIX?= FreeBSD
-PKG_MAINTAINER?= re@FreeBSD.org
-PKG_WWW?= https://www.FreeBSD.org
-.export PKG_NAME_PREFIX
-.export PKG_MAINTAINER
-.export PKG_WWW
.endif
.if !defined(_MKSHOWCONFIG)
@@ -1353,6 +1354,28 @@ __installcheck_DESTDIR: .PHONY
.endif
.endif
+#
+# Don't allow installworld or installkernel on a pkgbase system. This avoids
+# accidentally updating a pkgbase system with install{world,kernel}, causing
+# the installed system to become out of date with the package database.
+#
+# Skip the check if DESTDIR is defined on the assumption the user knows what
+# they're doing. This means the check can be disabled for the running system
+# using DESTDIR=/.
+#
+.if !make(distributeworld) && !defined(DESTDIR)
+_installcheck_world: __installcheck_PKG
+_installcheck_kernel: __installcheck_PKG
+__installcheck_PKG: .PHONY
+.if exists(${LOCALBASE}/sbin/pkg-static)
+ @if ${LOCALBASE}/sbin/pkg-static info -e ${PKG_NAME_PREFIX}-runtime; then \
+ echo >&2 "ERROR: This target should not be used on a system installed from packages." ; \
+ echo >&2 " To override this check, set DESTDIR=/."; \
+ false; \
+ fi
+.endif
+.endif
+
.if !defined(DB_FROM_SRC)
#
# Check for missing UIDs/GIDs.
diff --git a/UPDATING b/UPDATING
index 02541eb4b41c..448febb5ba1a 100644
--- a/UPDATING
+++ b/UPDATING
@@ -27,6 +27,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 16.x IS SLOW:
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20251021:
+ Bump __FreeBSD_version to 1600002 for LinuxKPI. An embedded struct
+ has changed size and might possibly be an issue otherwise.
+
20251016:
With the migration to OpenZFS in FreeBSD 13.x a number of ZFS sysctls
moved to new locations, but backwards compatibility aliases were
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index caca7d5cbdb9..f2dd4102fa04 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,3 +1,5 @@
+Oct 15, 2026: libarchive 3.8.2 released
+
Jun 01, 2026: libarchive 3.8.1 released
May 20, 2025: libarchive 3.8.0 released
diff --git a/contrib/libarchive/SECURITY.md b/contrib/libarchive/SECURITY.md
index 6ca188b603fe..f2f60e792a57 100644
--- a/contrib/libarchive/SECURITY.md
+++ b/contrib/libarchive/SECURITY.md
@@ -16,4 +16,4 @@ Please provide the following information in your report:
- How to reproduce the issue
This project is maintained by volunteers on a reasonable-effort basis. As such, we ask
-that you give me 90 days to work on a fix before public exposure.
+that you give us 90 days to work on a fix before public exposure.
diff --git a/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh b/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh
index 2aa4823fc3d0..b33aed5e5562 100755
--- a/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh
+++ b/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh
@@ -5,6 +5,9 @@ set -eux
#brew update > /dev/null
#brew upgrade > /dev/null
+# Workaround for cmake in local/pinned tap issue
+brew uninstall cmake
+
# This does an upgrade if the package is already installed
brew install \
autoconf \
diff --git a/contrib/libarchive/cat/bsdcat.c b/contrib/libarchive/cat/bsdcat.c
index 731621fa9b75..2e78870ae50e 100644
--- a/contrib/libarchive/cat/bsdcat.c
+++ b/contrib/libarchive/cat/bsdcat.c
@@ -7,6 +7,9 @@
#include "bsdcat_platform.h"
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -22,7 +25,7 @@
#include <archive_entry.h>
#include "bsdcat.h"
-#include "err.h"
+#include "lafe_err.h"
#define BYTES_PER_BLOCK (20*512)
@@ -105,6 +108,16 @@ main(int argc, char **argv)
bsdcat = &bsdcat_storage;
memset(bsdcat, 0, sizeof(*bsdcat));
+#if defined(HAVE_SIGACTION) && defined(SIGCHLD)
+ { /* Do not ignore SIGCHLD. */
+ struct sigaction sa;
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGCHLD, &sa, NULL);
+ }
+#endif
+
lafe_setprogname(*argv, "bsdcat");
bsdcat->argv = argv;
diff --git a/contrib/libarchive/cat/cmdline.c b/contrib/libarchive/cat/cmdline.c
index 8ecd74aa95e4..5a5fcaf0263f 100644
--- a/contrib/libarchive/cat/cmdline.c
+++ b/contrib/libarchive/cat/cmdline.c
@@ -22,7 +22,7 @@
#endif
#include "bsdcat.h"
-#include "err.h"
+#include "lafe_err.h"
/*
* Short options for bsdcat. Please keep this sorted.
diff --git a/contrib/libarchive/cpio/cmdline.c b/contrib/libarchive/cpio/cmdline.c
index c67519947dbc..db06c03c011d 100644
--- a/contrib/libarchive/cpio/cmdline.c
+++ b/contrib/libarchive/cpio/cmdline.c
@@ -26,7 +26,7 @@
#endif
#include "cpio.h"
-#include "err.h"
+#include "lafe_err.h"
/*
* Short options for cpio. Please keep this sorted.
diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c
index 2bf1bfa2985a..262db510568b 100644
--- a/contrib/libarchive/cpio/cpio.c
+++ b/contrib/libarchive/cpio/cpio.c
@@ -60,7 +60,7 @@
#endif
#include "cpio.h"
-#include "err.h"
+#include "lafe_err.h"
#include "line_reader.h"
#include "passphrase.h"
@@ -124,13 +124,21 @@ main(int argc, char *argv[])
cpio->buff_size = sizeof(buff);
-#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
- { /* Ignore SIGPIPE signals. */
+#if defined(HAVE_SIGACTION)
+ {
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
+#ifdef SIGPIPE
+ /* Ignore SIGPIPE signals. */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
+#endif
+#ifdef SIGCHLD
+ /* Do not ignore SIGCHLD. */
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &sa, NULL);
+#endif
}
#endif
diff --git a/contrib/libarchive/cpio/test/test_owner_parse.c b/contrib/libarchive/cpio/test/test_owner_parse.c
index dfc78ca77aec..bd68f21cec9b 100644
--- a/contrib/libarchive/cpio/test/test_owner_parse.c
+++ b/contrib/libarchive/cpio/test/test_owner_parse.c
@@ -7,7 +7,7 @@
#include "test.h"
#include "../cpio.h"
-#include "err.h"
+#include "lafe_err.h"
#if !defined(_WIN32)
#define ROOT "root"
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index 002190a24663..98d7674e18f1 100644
--- a/contrib/libarchive/libarchive/archive.h
+++ b/contrib/libarchive/libarchive/archive.h
@@ -34,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3008001
+#define ARCHIVE_VERSION_NUMBER 3008002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.8.1"
+#define ARCHIVE_VERSION_ONLY_STRING "3.8.2"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
diff --git a/contrib/libarchive/libarchive/archive_acl.c b/contrib/libarchive/libarchive/archive_acl.c
index 9e71f5ee5610..362e3308f43f 100644
--- a/contrib/libarchive/libarchive/archive_acl.c
+++ b/contrib/libarchive/libarchive/archive_acl.c
@@ -270,6 +270,19 @@ acl_new_entry(struct archive_acl *acl,
{
struct archive_acl_entry *ap, *aq;
+ /* Reject an invalid type */
+ switch (type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+ break;
+ default:
+ return (NULL);
+ }
+
/* Type argument must be a valid NFS4 or POSIX.1e type.
* The type must agree with anything already set and
* the permset must be compatible. */
@@ -822,6 +835,9 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
wname = NULL;
id = -1;
break;
+ default:
+ **wp = '\0';
+ break;
}
*wp += wcslen(*wp);
*(*wp)++ = L':';
@@ -878,6 +894,7 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
wcscpy(*wp, L"alarm");
break;
default:
+ *(*wp) = L'\0';
break;
}
*wp += wcslen(*wp);
@@ -1057,6 +1074,9 @@ append_entry(char **p, const char *prefix, int type,
name = NULL;
id = -1;
break;
+ default:
+ **p = '\0';
+ break;
}
*p += strlen(*p);
*(*p)++ = ':';
@@ -1112,6 +1132,9 @@ append_entry(char **p, const char *prefix, int type,
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
strcpy(*p, "alarm");
break;
+ default:
+ *(*p) = '\0';
+ break;
}
*p += strlen(*p);
}
diff --git a/contrib/libarchive/libarchive/archive_check_magic.c b/contrib/libarchive/libarchive/archive_check_magic.c
index d12f0c496e27..6b8e0c5595f4 100644
--- a/contrib/libarchive/libarchive/archive_check_magic.c
+++ b/contrib/libarchive/libarchive/archive_check_magic.c
@@ -30,6 +30,7 @@
#endif
#include <stdio.h>
+#include <errno.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -54,8 +55,14 @@ errmsg(const char *m)
while (s > 0) {
written = write(2, m, s);
- if (written <= 0)
+ if (written == 0)
return;
+ if (written < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return;
+ }
m += written;
s -= written;
}
diff --git a/contrib/libarchive/libarchive/archive_cryptor.c b/contrib/libarchive/libarchive/archive_cryptor.c
index 1825af4dc510..9f03f9ca6dd0 100644
--- a/contrib/libarchive/libarchive/archive_cryptor.c
+++ b/contrib/libarchive/libarchive/archive_cryptor.c
@@ -151,7 +151,7 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
(void)rounds; /* UNUSED */
(void)derived_key; /* UNUSED */
(void)derived_key_len; /* UNUSED */
- return -1; /* UNSUPPORTED */
+ return CRYPTOR_STUB_FUNCTION; /* UNSUPPORTED */
}
#endif
@@ -439,14 +439,14 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
(void)ctx; /* UNUSED */
(void)key; /* UNUSED */
(void)key_len; /* UNUSED */
- return -1;
+ return CRYPTOR_STUB_FUNCTION;
}
static int
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
{
(void)ctx; /* UNUSED */
- return -1;
+ return CRYPTOR_STUB_FUNCTION;
}
static int
@@ -469,7 +469,7 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
(void)out; /* UNUSED */
(void)out_len; /* UNUSED */
aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
- return -1;
+ return CRYPTOR_STUB_FUNCTION;
}
#else
diff --git a/contrib/libarchive/libarchive/archive_cryptor_private.h b/contrib/libarchive/libarchive/archive_cryptor_private.h
index 4b3c6c161433..1dbc5c17a01a 100644
--- a/contrib/libarchive/libarchive/archive_cryptor_private.h
+++ b/contrib/libarchive/libarchive/archive_cryptor_private.h
@@ -43,7 +43,7 @@ int __libarchive_cryptor_build_hack(void);
#ifdef __APPLE__
# include <AvailabilityMacros.h>
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
+# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 1
# endif
#endif
@@ -144,9 +144,15 @@ typedef struct {
#else
+#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
#if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
#define ARCHIVE_CRYPTOR_USE_WINCRYPT 1
#endif
+#endif
#define AES_BLOCK_SIZE 16
#define AES_MAX_KEY_SIZE 32
@@ -172,6 +178,9 @@ typedef int archive_crypto_ctx;
#define archive_encrypto_aes_ctr_release(ctx) \
__archive_cryptor.encrypto_aes_ctr_release(ctx)
+/* Stub return value if no encryption support exists. */
+#define CRYPTOR_STUB_FUNCTION -2
+
/* Minimal interface to cryptographic functionality for internal use in
* libarchive */
struct archive_cryptor
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index 2b917b3fde8e..344f33bffac2 100644
--- a/contrib/libarchive/libarchive/archive_entry.h
+++ b/contrib/libarchive/libarchive/archive_entry.h
@@ -28,7 +28,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3008001
+#define ARCHIVE_VERSION_NUMBER 3008002
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/contrib/libarchive/libarchive/archive_entry_paths.3 b/contrib/libarchive/libarchive/archive_entry_paths.3
index 0f849c9ebb35..f739b172308d 100644
--- a/contrib/libarchive/libarchive/archive_entry_paths.3
+++ b/contrib/libarchive/libarchive/archive_entry_paths.3
@@ -64,7 +64,7 @@ Streaming Archive Library (libarchive, -larchive)
.Ft void
.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
.Ft void
-.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
+.Fn archive_entry_copy_hardlink_w "struct archive_entry *a" "const wchar_t *path"
.Ft int
.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
.Ft void
diff --git a/contrib/libarchive/libarchive/archive_entry_stat.c b/contrib/libarchive/libarchive/archive_entry_stat.c
index c4906838ed0f..345d3d29b2f2 100644
--- a/contrib/libarchive/libarchive/archive_entry_stat.c
+++ b/contrib/libarchive/libarchive/archive_entry_stat.c
@@ -38,6 +38,7 @@
const struct stat *
archive_entry_stat(struct archive_entry *entry)
{
+ int64_t size;
struct stat *st;
if (entry->stat == NULL) {
entry->stat = calloc(1, sizeof(*st));
@@ -74,7 +75,10 @@ archive_entry_stat(struct archive_entry *entry)
st->st_ino = (ino_t)archive_entry_ino64(entry);
st->st_nlink = archive_entry_nlink(entry);
st->st_rdev = archive_entry_rdev(entry);
- st->st_size = (off_t)archive_entry_size(entry);
+ size = archive_entry_size(entry);
+ st->st_size = (off_t)size;
+ if (st->st_size < 0 || (int64_t)st->st_size != size)
+ st->st_size = 0;
st->st_mode = archive_entry_mode(entry);
/*
diff --git a/contrib/libarchive/libarchive/archive_parse_date.c b/contrib/libarchive/libarchive/archive_parse_date.c
index cda0b11a555f..d9e968387d34 100644
--- a/contrib/libarchive/libarchive/archive_parse_date.c
+++ b/contrib/libarchive/libarchive/archive_parse_date.c
@@ -703,9 +703,7 @@ Convert(time_t Month, time_t Day, time_t Year,
Year += 1900;
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
? 29 : 28;
- /* Checking for 2038 bogusly assumes that time_t is 32 bits. But
- I'm too lazy to try to check for time_t overflow in another way. */
- if (Year < EPOCH || Year >= 2038
+ if (Year < EPOCH || (sizeof(time_t) <= 4 && Year >= 2038)
|| Month < 1 || Month > 12
/* Lint fluff: "conversion from long may lose accuracy" */
|| Day < 1 || Day > DaysInMonth[(int)--Month]
diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h
index f30df1104c83..33dc5582b7ed 100644
--- a/contrib/libarchive/libarchive/archive_platform.h
+++ b/contrib/libarchive/libarchive/archive_platform.h
@@ -183,16 +183,6 @@
#define CAN_RESTORE_METADATA_FD
#endif
-/*
- * glibc 2.24 deprecates readdir_r
- * bionic c deprecates readdir_r too
- */
-#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
-#define USE_READDIR_R 1
-#else
-#undef USE_READDIR_R
-#endif
-
/* Set up defaults for internal error codes. */
#ifndef ARCHIVE_ERRNO_FILE_FORMAT
#if HAVE_EFTYPE
diff --git a/contrib/libarchive/libarchive/archive_platform_stat.h b/contrib/libarchive/libarchive/archive_platform_stat.h
new file mode 100644
index 000000000000..5432b2f6433a
--- /dev/null
+++ b/contrib/libarchive/libarchive/archive_platform_stat.h
@@ -0,0 +1,45 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Tobias Stoeckmann
+ * All rights reserved.
+ */
+
+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
+
+#ifndef ARCHIVE_PLATFORM_STAT_H_INCLUDED
+#define ARCHIVE_PLATFORM_STAT_H_INCLUDED
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+/* We use _lseeki64() on Windows. */
+typedef int64_t la_seek_t;
+
+struct la_seek_stat {
+ int64_t st_mtime;
+ ino_t st_ino;
+ unsigned short st_mode;
+ uint32_t st_nlink;
+ gid_t st_gid;
+ la_seek_t st_size;
+ uid_t st_uid;
+ dev_t st_dev;
+ dev_t st_rdev;
+};
+typedef struct la_seek_stat la_seek_stat_t;
+
+#define la_seek_fstat(fd, st) __la_seek_fstat((fd), (st))
+#define la_seek_stat(fd, st) __la_seek_stat((fd), (st))
+
+#else
+typedef off_t la_seek_t;
+typedef struct stat la_seek_stat_t;
+
+#define la_seek_fstat(fd, st) fstat((fd), (st))
+#define la_seek_stat(fd, st) stat((fd), (st))
+#endif
+
+#endif /* !ARCHIVE_PLATFORM_STAT_H_INCLUDED */
diff --git a/contrib/libarchive/libarchive/archive_private.h b/contrib/libarchive/libarchive/archive_private.h
index 050fc63c0b2e..3a926c6886ad 100644
--- a/contrib/libarchive/libarchive/archive_private.h
+++ b/contrib/libarchive/libarchive/archive_private.h
@@ -158,6 +158,7 @@ int __archive_check_magic(struct archive *, unsigned int magic,
__LA_NORETURN void __archive_errx(int retvalue, const char *msg);
void __archive_ensure_cloexec_flag(int fd);
+int __archive_get_tempdir(struct archive_string *);
int __archive_mktemp(const char *tmpdir);
#if defined(_WIN32) && !defined(__CYGWIN__)
int __archive_mkstemp(wchar_t *templates);
diff --git a/contrib/libarchive/libarchive/archive_read.c b/contrib/libarchive/libarchive/archive_read.c
index 50db87017706..c9b9d5981516 100644
--- a/contrib/libarchive/libarchive/archive_read.c
+++ b/contrib/libarchive/libarchive/archive_read.c
@@ -575,8 +575,7 @@ choose_filters(struct archive_read *a)
return (ARCHIVE_OK);
}
- filter
- = calloc(1, sizeof(*filter));
+ filter = calloc(1, sizeof(*filter));
if (filter == NULL)
return (ARCHIVE_FATAL);
filter->bidder = best_bidder;
@@ -834,7 +833,9 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
r = archive_read_data_block(a, &read_buf,
&a->read_data_remaining, &a->read_data_offset);
a->read_data_block = read_buf;
- if (r == ARCHIVE_EOF)
+ if (r == ARCHIVE_EOF &&
+ a->read_data_offset == a->read_data_output_offset &&
+ a->read_data_remaining == 0)
return (bytes_read);
/*
* Error codes are all negative, so the status
diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
index 19d049770b78..42af4034b07e 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -338,7 +338,7 @@ setup_mac_metadata(struct archive_read_disk *a,
int ret = ARCHIVE_OK;
void *buff = NULL;
int have_attrs;
- const char *name, *tempdir;
+ const char *name;
struct archive_string tempfile;
(void)fd; /* UNUSED */
@@ -357,13 +357,11 @@ setup_mac_metadata(struct archive_read_disk *a,
if (have_attrs == 0)
return (ARCHIVE_OK);
- tempdir = NULL;
- if (issetugid() == 0)
- tempdir = getenv("TMPDIR");
- if (tempdir == NULL)
- tempdir = _PATH_TMP;
archive_string_init(&tempfile);
- archive_strcpy(&tempfile, tempdir);
+ if (__archive_get_tempdir(&tempfile) != ARCHIVE_OK) {
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
archive_strcat(&tempfile, "tar.md.XXXXXX");
tempfd = mkstemp(tempfile.s);
if (tempfd < 0) {
diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c
index a7a98e9cb1cd..54a8e66188f8 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c
@@ -168,9 +168,6 @@ struct filesystem {
int synthetic;
int remote;
int noatime;
-#if defined(USE_READDIR_R)
- size_t name_max;
-#endif
long incr_xfer_size;
long max_xfer_size;
long min_xfer_size;
@@ -203,10 +200,6 @@ struct tree {
DIR *d;
#define INVALID_DIR_HANDLE NULL
struct dirent *de;
-#if defined(USE_READDIR_R)
- struct dirent *dirent;
- size_t dirent_allocated;
-#endif
int flags;
int visit_type;
/* Error code from last failed operation. */
@@ -869,7 +862,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
tree_enter_initial_dir(t);
return (ARCHIVE_FATAL);
case TREE_ERROR_DIR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, t->tree_errno,
"%s: Couldn't visit directory",
tree_current_path(t));
tree_enter_initial_dir(t);
@@ -1578,9 +1571,6 @@ setup_current_filesystem(struct archive_read_disk *a)
# endif
#endif
int r, xr = 0;
-#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
- long nm;
-#endif
t->current_filesystem->synthetic = -1;
t->current_filesystem->remote = -1;
@@ -1647,35 +1637,6 @@ setup_current_filesystem(struct archive_read_disk *a)
#endif
t->current_filesystem->noatime = 0;
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
-#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
- t->current_filesystem->name_max = sfs.f_namemax;
-#else
-# if defined(_PC_NAME_MAX)
- /* Mac OS X does not have f_namemax in struct statfs. */
- if (tree_current_is_symblic_link_target(t)) {
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
- } else
- nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
-# else
- nm = -1;
-# endif
- if (nm == -1)
- t->current_filesystem->name_max = NAME_MAX;
- else
- t->current_filesystem->name_max = nm;
-#endif
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif /* USE_READDIR_R */
return (ARCHIVE_OK);
}
@@ -1863,19 +1824,6 @@ setup_current_filesystem(struct archive_read_disk *a)
#endif
t->current_filesystem->noatime = 0;
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
-#if defined(HAVE_STATVFS)
- t->current_filesystem->name_max = svfs.f_namemax;
-#else
- t->current_filesystem->name_max = sfs.f_namelen;
-#endif
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif
return (ARCHIVE_OK);
}
@@ -1953,15 +1901,6 @@ setup_current_filesystem(struct archive_read_disk *a)
#endif
t->current_filesystem->noatime = 0;
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
- t->current_filesystem->name_max = svfs.f_namemax;
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif
return (ARCHIVE_OK);
}
@@ -1975,9 +1914,6 @@ static int
setup_current_filesystem(struct archive_read_disk *a)
{
struct tree *t = a->tree;
-#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R)
- long nm;
-#endif
t->current_filesystem->synthetic = -1;/* Not supported */
t->current_filesystem->remote = -1;/* Not supported */
t->current_filesystem->noatime = 0;
@@ -1987,40 +1923,6 @@ setup_current_filesystem(struct archive_read_disk *a)
t->current_filesystem->min_xfer_size = -1;
t->current_filesystem->incr_xfer_size = -1;
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
-# if defined(_PC_NAME_MAX)
- if (tree_current_is_symblic_link_target(t)) {
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
- } else
- nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
- if (nm == -1)
-# endif /* _PC_NAME_MAX */
- /*
- * Some systems (HP-UX or others?) incorrectly defined
- * NAME_MAX macro to be a smaller value.
- */
-# if defined(NAME_MAX) && NAME_MAX >= 255
- t->current_filesystem->name_max = NAME_MAX;
-# else
- /* No way to get a trusted value of maximum filename
- * length. */
- t->current_filesystem->name_max = PATH_MAX;
-# endif /* NAME_MAX */
-# if defined(_PC_NAME_MAX)
- else
- t->current_filesystem->name_max = nm;
-# endif /* _PC_NAME_MAX */
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif /* USE_READDIR_R */
return (ARCHIVE_OK);
}
@@ -2112,8 +2014,11 @@ tree_dup(int fd)
}
#endif /* F_DUPFD_CLOEXEC */
new_fd = dup(fd);
- __archive_ensure_cloexec_flag(new_fd);
- return (new_fd);
+ if (new_fd != -1) {
+ __archive_ensure_cloexec_flag(new_fd);
+ return (new_fd);
+ }
+ return (-1);
}
/*
@@ -2235,11 +2140,16 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
* so try again for execute. The consequences of not opening this are
* unhelpful and unnecessary errors later.
*/
- if (t->initial_dir_fd < 0)
+ if (t->initial_dir_fd < 0) {
t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
+ if (t->initial_dir_fd < 0)
+ return NULL;
+ }
#endif
__archive_ensure_cloexec_flag(t->initial_dir_fd);
t->working_dir_fd = tree_dup(t->initial_dir_fd);
+ if (t->working_dir_fd < 0)
+ return NULL;
return (t);
}
@@ -2449,12 +2359,11 @@ tree_dir_next_posix(struct tree *t)
size_t namelen;
if (t->d == NULL) {
-#if defined(USE_READDIR_R)
- size_t dirent_size;
-#endif
#if defined(HAVE_FDOPENDIR)
- t->d = fdopendir(tree_dup(t->working_dir_fd));
+ int fd = tree_dup(t->working_dir_fd);
+ if (fd != -1)
+ t->d = fdopendir(fd);
#else /* HAVE_FDOPENDIR */
if (tree_enter_working_dir(t) == 0) {
t->d = opendir(".");
@@ -2470,45 +2379,12 @@ tree_dir_next_posix(struct tree *t)
t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
return (t->visit_type);
}
-#if defined(USE_READDIR_R)
- dirent_size = offsetof(struct dirent, d_name) +
- t->filesystem_table[t->current->filesystem_id].name_max + 1;
- if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
- free(t->dirent);
- t->dirent = malloc(dirent_size);
- if (t->dirent == NULL) {
- closedir(t->d);
- t->d = INVALID_DIR_HANDLE;
- (void)tree_ascend(t);
- tree_pop(t);
- t->tree_errno = ENOMEM;
- t->visit_type = TREE_ERROR_DIR;
- return (t->visit_type);
- }
- t->dirent_allocated = dirent_size;
- }
-#endif /* USE_READDIR_R */
}
for (;;) {
errno = 0;
-#if defined(USE_READDIR_R)
- r = readdir_r(t->d, t->dirent, &t->de);
-#ifdef _AIX
- /* Note: According to the man page, return value 9 indicates
- * that the readdir_r was not successful and the error code
- * is set to the global errno variable. And then if the end
- * of directory entries was reached, the return value is 9
- * and the third parameter is set to NULL and errno is
- * unchanged. */
- if (r == 9)
- r = errno;
-#endif /* _AIX */
- if (r != 0 || t->de == NULL) {
-#else
t->de = readdir(t->d);
if (t->de == NULL) {
r = errno;
-#endif
closedir(t->d);
t->d = INVALID_DIR_HANDLE;
if (r != 0) {
@@ -2747,9 +2623,6 @@ tree_free(struct tree *t)
if (t == NULL)
return;
archive_string_free(&t->path);
-#if defined(USE_READDIR_R)
- free(t->dirent);
-#endif
free(t->sparse_list);
for (i = 0; i < t->max_filesystem_id; i++)
free(t->filesystem_table[i].allocation_ptr);
diff --git a/contrib/libarchive/libarchive/archive_read_open_fd.c b/contrib/libarchive/libarchive/archive_read_open_fd.c
index dc7c9e52c6f6..c85a62a3e2d7 100644
--- a/contrib/libarchive/libarchive/archive_read_open_fd.c
+++ b/contrib/libarchive/libarchive/archive_read_open_fd.c
@@ -48,6 +48,7 @@
#endif
#include "archive.h"
+#include "archive_platform_stat.h"
struct read_fd_data {
int fd;
@@ -65,12 +66,12 @@ static int64_t file_skip(struct archive *, void *, int64_t request);
int
archive_read_open_fd(struct archive *a, int fd, size_t block_size)
{
- struct stat st;
+ la_seek_stat_t st;
struct read_fd_data *mine;
void *b;
archive_clear_error(a);
- if (fstat(fd, &st) != 0) {
+ if (la_seek_fstat(fd, &st) != 0) {
archive_set_error(a, errno, "Can't stat fd %d", fd);
return (ARCHIVE_FATAL);
}
@@ -133,7 +134,7 @@ static int64_t
file_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_fd_data *mine = (struct read_fd_data *)client_data;
- off_t skip = (off_t)request;
+ la_seek_t skip = (la_seek_t)request;
int64_t old_offset, new_offset;
int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
@@ -149,7 +150,8 @@ file_skip(struct archive *a, void *client_data, int64_t request)
}
/* Reduce 'skip' to the next smallest multiple of block_size */
- skip = (off_t)(((int64_t)skip / mine->block_size) * mine->block_size);
+ skip = (la_seek_t)(((int64_t)skip / mine->block_size) * mine->block_size);
+
if (skip == 0)
return (0);
@@ -185,27 +187,28 @@ static int64_t
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
{
struct read_fd_data *mine = (struct read_fd_data *)client_data;
- off_t seek = (off_t)request;
+ la_seek_t seek = (la_seek_t)request;
int64_t r;
int seek_bits = sizeof(seek) * 8 - 1; /* off_t is a signed type. */
/* We use off_t here because lseek() is declared that way. */
- /* Reduce a request that would overflow the 'seek' variable. */
+ /* Do not perform a seek which cannot be fulfilled. */
if (sizeof(request) > sizeof(seek)) {
const int64_t max_seek =
(((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
const int64_t min_seek = ~max_seek;
- if (request > max_seek)
- seek = (off_t)max_seek;
- else if (request < min_seek)
- seek = (off_t)min_seek;
+ if (request < min_seek || request > max_seek) {
+ errno = EOVERFLOW;
+ goto err;
+ }
}
r = lseek(mine->fd, seek, whence);
if (r >= 0)
return r;
+err:
if (errno == ESPIPE) {
archive_set_error(a, errno,
"A file descriptor(%d) is not seekable(PIPE)", mine->fd);
diff --git a/contrib/libarchive/libarchive/archive_read_open_file.c b/contrib/libarchive/libarchive/archive_read_open_file.c
index 742923abbee9..6ca2ff191aa8 100644
--- a/contrib/libarchive/libarchive/archive_read_open_file.c
+++ b/contrib/libarchive/libarchive/archive_read_open_file.c
@@ -48,6 +48,7 @@
#endif
#include "archive.h"
+#include "archive_platform_stat.h"
struct read_FILE_data {
FILE *f;
@@ -65,7 +66,7 @@ static int64_t FILE_skip(struct archive *, void *, int64_t);
int
archive_read_open_FILE(struct archive *a, FILE *f)
{
- struct stat st;
+ la_seek_stat_t st;
struct read_FILE_data *mine;
size_t block_size = 128 * 1024;
void *b;
@@ -88,7 +89,7 @@ archive_read_open_FILE(struct archive *a, FILE *f)
* streams that don't support fileno()). As a result, fileno()
* should be used cautiously.)
*/
- if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
+ if (la_seek_fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
/* Enable the seek optimization only for regular files. */
mine->can_skip = 1;
@@ -205,15 +206,15 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
int seek_bits = sizeof(seek) * 8 - 1;
(void)a; /* UNUSED */
- /* Reduce a request that would overflow the 'seek' variable. */
+ /* Do not perform a seek which cannot be fulfilled. */
if (sizeof(request) > sizeof(seek)) {
const int64_t max_seek =
(((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
const int64_t min_seek = ~max_seek;
- if (request > max_seek)
- seek = max_seek;
- else if (request < min_seek)
- seek = min_seek;
+ if (request < min_seek || request > max_seek) {
+ errno = EOVERFLOW;
+ goto err;
+ }
}
#ifdef __ANDROID__
@@ -236,6 +237,7 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
}
#endif
/* If we arrive here, the input is corrupted or truncated so fail. */
+err:
archive_set_error(a, errno, "Error seeking in FILE* pointer");
return (ARCHIVE_FATAL);
}
diff --git a/contrib/libarchive/libarchive/archive_read_open_filename.c b/contrib/libarchive/libarchive/archive_read_open_filename.c
index 5f5b3f1f7259..a910eefcbfd2 100644
--- a/contrib/libarchive/libarchive/archive_read_open_filename.c
+++ b/contrib/libarchive/libarchive/archive_read_open_filename.c
@@ -59,6 +59,7 @@
#endif
#include "archive.h"
+#include "archive_platform_stat.h"
#include "archive_private.h"
#include "archive_string.h"
@@ -136,8 +137,10 @@ archive_read_open_filenames(struct archive *a, const char **filenames,
mine->filename_type = FNT_STDIN;
} else
mine->filename_type = FNT_MBS;
- if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
+ if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) {
+ free(mine);
return (ARCHIVE_FATAL);
+ }
if (filenames == NULL)
break;
filename = *(filenames++);
@@ -216,8 +219,10 @@ archive_read_open_filenames_w(struct archive *a, const wchar_t **wfilenames,
archive_string_free(&fn);
#endif
}
- if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
+ if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) {
+ free(mine);
return (ARCHIVE_FATAL);
+ }
if (wfilenames == NULL)
break;
wfilename = *(wfilenames++);
@@ -248,7 +253,7 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
static int
file_open(struct archive *a, void *client_data)
{
- struct stat st;
+ la_seek_stat_t st;
struct read_file_data *mine = (struct read_file_data *)client_data;
void *buffer;
const char *filename = NULL;
@@ -313,7 +318,7 @@ file_open(struct archive *a, void *client_data)
goto fail;
#endif
}
- if (fstat(fd, &st) != 0) {
+ if (la_seek_fstat(fd, &st) != 0) {
#if defined(_WIN32) && !defined(__CYGWIN__)
if (mine->filename_type == FNT_WCS)
archive_set_error(a, errno, "Can't stat '%ls'",
@@ -482,10 +487,11 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
struct read_file_data *mine = (struct read_file_data *)client_data;
#if defined(_WIN32) && !defined(__CYGWIN__)
/* We use _lseeki64() on Windows. */
- int64_t old_offset, new_offset, skip = request;
+ int64_t old_offset, new_offset;
#else
- off_t old_offset, new_offset, skip = (off_t)request;
+ off_t old_offset, new_offset;
#endif
+ la_seek_t skip = (la_seek_t)request;
int skip_bits = sizeof(skip) * 8 - 1;
/* We use off_t here because lseek() is declared that way. */
@@ -552,21 +558,21 @@ static int64_t
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
- off_t seek = (off_t)request;
+ la_seek_t seek = (la_seek_t)request;
int64_t r;
int seek_bits = sizeof(seek) * 8 - 1;
/* We use off_t here because lseek() is declared that way. */
- /* Reduce a request that would overflow the 'seek' variable. */
+ /* Do not perform a seek which cannot be fulfilled. */
if (sizeof(request) > sizeof(seek)) {
const int64_t max_seek =
(((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
const int64_t min_seek = ~max_seek;
- if (request > max_seek)
- seek = (off_t)max_seek;
- else if (request < min_seek)
- seek = (off_t)min_seek;
+ if (request < min_seek || request > max_seek) {
+ errno = EOVERFLOW;
+ goto err;
+ }
}
r = lseek(mine->fd, seek, whence);
@@ -574,6 +580,7 @@ file_seek(struct archive *a, void *client_data, int64_t request, int whence)
return r;
/* If the input is corrupted or truncated, fail. */
+err:
if (mine->filename_type == FNT_STDIN)
archive_set_error(a, errno, "Error seeking in stdin");
else if (mine->filename_type == FNT_MBS)
diff --git a/contrib/libarchive/libarchive/archive_read_set_format.c b/contrib/libarchive/libarchive/archive_read_set_format.c
index c74361b20c13..552ab12d2f92 100644
--- a/contrib/libarchive/libarchive/archive_read_set_format.c
+++ b/contrib/libarchive/libarchive/archive_read_set_format.c
@@ -37,7 +37,7 @@ int
archive_read_set_format(struct archive *_a, int code)
{
int r1, r2, slots, i;
- char str[10];
+ const char *str;
struct archive_read *a = (struct archive_read *)_a;
if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
@@ -49,49 +49,49 @@ archive_read_set_format(struct archive *_a, int code)
switch (code & ARCHIVE_FORMAT_BASE_MASK)
{
case ARCHIVE_FORMAT_7ZIP:
- strcpy(str, "7zip");
+ str = "7zip";
break;
case ARCHIVE_FORMAT_AR:
- strcpy(str, "ar");
+ str = "ar";
break;
case ARCHIVE_FORMAT_CAB:
- strcpy(str, "cab");
+ str = "cab";
break;
case ARCHIVE_FORMAT_CPIO:
- strcpy(str, "cpio");
+ str = "cpio";
break;
case ARCHIVE_FORMAT_EMPTY:
- strcpy(str, "empty");
+ str = "empty";
break;
case ARCHIVE_FORMAT_ISO9660:
- strcpy(str, "iso9660");
+ str = "iso9660";
break;
case ARCHIVE_FORMAT_LHA:
- strcpy(str, "lha");
+ str = "lha";
break;
case ARCHIVE_FORMAT_MTREE:
- strcpy(str, "mtree");
+ str = "mtree";
break;
case ARCHIVE_FORMAT_RAR:
- strcpy(str, "rar");
+ str = "rar";
break;
case ARCHIVE_FORMAT_RAR_V5:
- strcpy(str, "rar5");
+ str = "rar5";
break;
case ARCHIVE_FORMAT_RAW:
- strcpy(str, "raw");
+ str = "raw";
break;
case ARCHIVE_FORMAT_TAR:
- strcpy(str, "tar");
+ str = "tar";
break;
case ARCHIVE_FORMAT_WARC:
- strcpy(str, "warc");
+ str = "warc";
break;
case ARCHIVE_FORMAT_XAR:
- strcpy(str, "xar");
+ str = "xar";
break;
case ARCHIVE_FORMAT_ZIP:
- strcpy(str, "zip");
+ str = "zip";
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_program.c b/contrib/libarchive/libarchive/archive_read_support_filter_program.c
index 9e825223b26c..2c8e45302d8e 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_program.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_program.c
@@ -110,7 +110,7 @@ struct program_filter {
pid_t child;
#endif
int exit_status;
- int waitpid_return;
+ pid_t waitpid_return;
int child_stdin, child_stdout;
char *out_buf;
@@ -242,16 +242,13 @@ child_stop(struct archive_read_filter *self, struct program_filter *state)
state->waitpid_return
= waitpid(state->child, &state->exit_status, 0);
} while (state->waitpid_return == -1 && errno == EINTR);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- CloseHandle(state->child);
-#endif
state->child = 0;
}
if (state->waitpid_return < 0) {
/* waitpid() failed? This is ugly. */
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Child process exited badly");
+ "Error closing child process");
return (ARCHIVE_WARN);
}
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
index f273f84be521..595462733104 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
@@ -80,7 +80,7 @@
/*
* ELF format
*/
-#define ELF_HDR_MIN_LEN 0x34
+#define ELF_HDR_MIN_LEN 0x3f
#define ELF_HDR_EI_CLASS_OFFSET 0x04
#define ELF_HDR_EI_DATA_OFFSET 0x05
@@ -811,6 +811,8 @@ find_elf_data_sec(struct archive_read *a)
strtab_size = (*dec32)(
h + e_shstrndx * e_shentsize + 0x14);
}
+ if (strtab_size < 6 || strtab_size > SIZE_MAX)
+ break;
/*
* Read the STRTAB section to find the .data offset
@@ -1391,7 +1393,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
* size to liblzma when using lzma_raw_decoder() liblzma
* could correctly deal with BCJ+LZMA. But unfortunately
* there is no way to do that.
- * Discussion about this can be found at XZ Utils forum.
+ *
+ * Reference: https://web.archive.org/web/20240405171610/https://www.mail-archive.com/xz-devel@tukaani.org/msg00373.html
*/
if (coder2 != NULL) {
zip->codec2 = coder2->codec;
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
index ba0e49de2408..ded13bee79a3 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
@@ -51,6 +51,7 @@
#include "archive.h"
#include "archive_entry.h"
#include "archive_entry_private.h"
+#include "archive_platform_stat.h"
#include "archive_private.h"
#include "archive_rb.h"
#include "archive_read_private.h"
@@ -1073,6 +1074,8 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
/* Non-printable characters are not allowed */
for (s = p;s < p + len - 1; s++) {
if (!isprint((unsigned char)*s) && *s != '\t') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Non-printable character 0x%02X", (unsigned char)(*s));
r = ARCHIVE_FATAL;
break;
}
@@ -1175,7 +1178,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
{
const char *path;
- struct stat st_storage, *st;
+ la_seek_stat_t st_storage, *st;
struct mtree_entry *mp;
struct archive_entry *sparse_entry;
int r = ARCHIVE_OK, r1, parsed_kws;
@@ -1251,7 +1254,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
archive_entry_filetype(entry) == AE_IFDIR) {
mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
__archive_ensure_cloexec_flag(mtree->fd);
- if (mtree->fd == -1 && (
+ if (mtree->fd < 0 && (
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
* On Windows, attempting to open a file with an
@@ -1270,7 +1273,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
st = &st_storage;
if (mtree->fd >= 0) {
- if (fstat(mtree->fd, st) == -1) {
+ if (la_seek_fstat(mtree->fd, st) == -1) {
archive_set_error(&a->archive, errno,
"Could not fstat %s", path);
r = ARCHIVE_WARN;
@@ -1283,7 +1286,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
#ifdef HAVE_LSTAT
else if (lstat(path, st) == -1)
#else
- else if (la_stat(path, st) == -1)
+ else if (la_seek_stat(path, st) == -1)
#endif
{
st = NULL;
@@ -2130,6 +2133,13 @@ readline(struct archive_read *a, struct mtree *mtree, char **start,
for (u = mtree->line.s + find_off; *u; ++u) {
if (u[0] == '\n') {
/* Ends with unescaped newline. */
+ /* Check if preceded by '\r' for CRLF handling */
+ if (u > mtree->line.s && u[-1] == '\r') {
+ /* CRLF ending - remove the '\r' */
+ u[-1] = '\n';
+ u[0] = '\0';
+ total_size--;
+ }
*start = mtree->line.s;
return total_size;
} else if (u[0] == '#') {
@@ -2144,6 +2154,11 @@ readline(struct archive_read *a, struct mtree *mtree, char **start,
total_size -= 2;
mtree->line.s[total_size] = '\0';
break;
+ } else if (u[1] == '\r' && u[2] == '\n') {
+ /* Trim escaped CRLF. */
+ total_size -= 3;
+ mtree->line.s[total_size] = '\0';
+ break;
} else if (u[1] != '\0') {
/* Skip the two-char escape sequence */
++u;
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c
index 923ae5c65e17..9b401c00ba34 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c
@@ -1117,8 +1117,6 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
*size = 0;
*offset = rar->offset;
- if (*offset < rar->unp_size)
- *offset = rar->unp_size;
return (ARCHIVE_EOF);
}
@@ -1455,7 +1453,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
#endif
}
- /* If no CRC error, Go on parsing File Header. */
+ /* If no CRC error, go on parsing File Header. */
p = h;
endp = p + header_size - 7;
memcpy(&file_header, p, sizeof(file_header));
@@ -2368,8 +2366,8 @@ parse_codes(struct archive_read *a)
return (ARCHIVE_FATAL);
}
- /* Make sure ppmd7_contest is freed before Ppmd7_Construct
- * because reading a broken file cause this abnormal sequence. */
+ /* Make sure ppmd7_context is freed before Ppmd7_Construct
+ * because reading a broken file causes this abnormal sequence. */
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
rar->bytein.a = a;
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
index 48dde0c2e814..17e501e02e9f 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
@@ -1619,10 +1619,13 @@ static int process_head_file_extra(struct archive_read* a,
{
uint64_t extra_field_size;
uint64_t extra_field_id = 0;
- int ret = ARCHIVE_FATAL;
uint64_t var_size;
while(extra_data_size > 0) {
+ /* Make sure we won't fail if the file declares only unsupported
+ attributes. */
+ int ret = ARCHIVE_OK;
+
if(!read_var(a, &extra_field_size, &var_size))
return ARCHIVE_EOF;
@@ -1675,12 +1678,53 @@ static int process_head_file_extra(struct archive_read* a,
if (ARCHIVE_OK != consume(a, extra_field_size)) {
return ARCHIVE_EOF;
}
+
+ /* Don't fail on unsupported attribute -- we've handled it
+ by skipping over it. */
+ ret = ARCHIVE_OK;
+ }
+
+ if (ret != ARCHIVE_OK) {
+ /* Forward any errors signalled by the attribute parsing
+ functions. */
+ return ret;
}
}
- if(ret != ARCHIVE_OK) {
- /* Attribute not implemented. */
- return ret;
+ if (extra_data_size != 0) {
+ /* We didn't skip everything, or we skipped too much; either way,
+ there's an error in this parsing function. */
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "unsupported structure of file header extra data");
+ return ARCHIVE_FATAL;
+ }
+
+ return ARCHIVE_OK;
+}
+
+static int file_entry_sanity_checks(struct archive_read* a,
+ size_t block_flags, uint8_t is_dir, uint64_t unpacked_size,
+ size_t packed_size)
+{
+ if (is_dir) {
+ const int declares_data_size =
+ (int) (unpacked_size != 0 || packed_size != 0);
+
+ /* FILE entries for directories still declare HFL_DATA in block flags,
+ even though attaching data to such blocks doesn't make much sense. */
+ if (declares_data_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "directory entries cannot have any data");
+ return ARCHIVE_FATAL;
+ }
+ } else {
+ const int declares_hfl_data = (int) ((block_flags & HFL_DATA) != 0);
+ if (!declares_hfl_data) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "no data found in file/service block");
+ return ARCHIVE_FATAL;
+ }
}
return ARCHIVE_OK;
@@ -1701,6 +1745,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
int c_method = 0, c_version = 0;
char name_utf8_buf[MAX_NAME_IN_BYTES];
const uint8_t* p;
+ int sanity_ret;
enum FILE_FLAGS {
DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
@@ -1744,10 +1789,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
rar->file.bytes_remaining = data_size;
} else {
rar->file.bytes_remaining = 0;
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "no data found in file/service block");
- return ARCHIVE_FATAL;
}
if(!read_var_sized(a, &file_flags, NULL))
@@ -1764,6 +1805,13 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0);
+ sanity_ret = file_entry_sanity_checks(a, block_flags, rar->file.dir,
+ unpacked_size, data_size);
+
+ if (sanity_ret != ARCHIVE_OK) {
+ return sanity_ret;
+ }
+
if(!read_var_sized(a, &file_attr, NULL))
return ARCHIVE_EOF;
@@ -4163,7 +4211,7 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
* it's impossible to perform any decompression. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Can't decompress an entry marked as a directory");
- return ARCHIVE_FAILED;
+ return ARCHIVE_FATAL;
}
if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) {
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
index 0c87bc6d732f..eeb2c725f6eb 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
@@ -233,7 +233,7 @@ static int tar_read_header(struct archive_read *, struct tar *,
struct archive_entry *, int64_t *);
static int tohex(int c);
static char *url_decode(const char *, size_t);
-static void tar_flush_unconsumed(struct archive_read *, int64_t *);
+static int tar_flush_unconsumed(struct archive_read *, int64_t *);
/* Sanity limits: These numbers should be low enough to
* prevent a maliciously-crafted archive from forcing us to
@@ -477,7 +477,7 @@ archive_read_format_tar_options(struct archive_read *a,
* how much unconsumed data we have floating around, and to consume
* anything outstanding since we're going to do read_aheads
*/
-static void
+static int
tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed)
{
if (*unconsumed) {
@@ -490,9 +490,13 @@ tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed)
memset(data, 0xff, *unconsumed);
}
*/
- __archive_read_consume(a, *unconsumed);
+ int64_t consumed = __archive_read_consume(a, *unconsumed);
+ if (consumed != *unconsumed) {
+ return (ARCHIVE_FATAL);
+ }
*unconsumed = 0;
}
+ return (ARCHIVE_OK);
}
/*
@@ -750,7 +754,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
/* Find the next valid header record. */
while (1) {
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
/* Read 512-byte header record */
h = __archive_read_ahead(a, 512, &bytes);
@@ -796,7 +802,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
/* This is NOT a null block, so it must be a valid header. */
if (!checksum(a, h)) {
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
archive_set_error(&a->archive, EINVAL,
"Damaged tar archive (bad header checksum)");
/* If we've read some critical information (pax headers, etc)
@@ -1236,7 +1244,7 @@ header_volume(struct archive_read *a, struct tar *tar,
header = (const struct archive_entry_header_ustar *)h;
size = tar_atol(header->size, sizeof(header->size));
- if (size > (int64_t)pathname_limit) {
+ if (size < 0 || size > (int64_t)pathname_limit) {
return (ARCHIVE_FATAL);
}
to_consume = ((size + 511) & ~511);
@@ -1255,13 +1263,15 @@ read_bytes_to_string(struct archive_read *a,
const void *src;
/* Fail if we can't make our buffer big enough. */
- if (archive_string_ensure(as, (size_t)size+1) == NULL) {
+ if (archive_string_ensure(as, size + 1) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory");
return (ARCHIVE_FATAL);
}
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
/* Read the body into the string. */
src = __archive_read_ahead(a, size, NULL);
@@ -1272,9 +1282,9 @@ read_bytes_to_string(struct archive_read *a,
*unconsumed = 0;
return (ARCHIVE_FATAL);
}
- memcpy(as->s, src, (size_t)size);
+ memcpy(as->s, src, size);
as->s[size] = '\0';
- as->length = (size_t)size;
+ as->length = size;
*unconsumed += size;
return (ARCHIVE_OK);
}
@@ -1715,7 +1725,9 @@ read_mac_metadata_blob(struct archive_read *a,
* Q: Is the above idea really possible? Even
* when there are GNU or pax extension entries?
*/
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
data = __archive_read_ahead(a, msize, NULL);
if (data == NULL) {
archive_set_error(&a->archive, EINVAL,
@@ -1900,7 +1912,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
(long long)ext_size, (long long)ext_size_limit);
return (ARCHIVE_WARN);
}
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
/* Parse the size/name of each pax attribute in the body */
archive_string_init(&attr_name);
@@ -1994,7 +2008,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
/* Consume size, name, and `=` */
*unconsumed += p - attr_start;
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
if (value_length == 0) {
archive_set_error(&a->archive, EINVAL,
@@ -2017,7 +2033,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
err = err_combine(err, r);
/* Consume the `\n` that follows the pax attribute value. */
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
p = __archive_read_ahead(a, 1, &did_read);
if (p == NULL) {
archive_set_error(&a->archive, EINVAL,
@@ -2033,7 +2051,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar,
}
ext_size -= 1;
*unconsumed += 1;
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
}
*unconsumed += ext_size + ext_padding;
@@ -2290,7 +2310,9 @@ pax_attribute_read_number(struct archive_read *a, size_t value_length, int64_t *
archive_string_init(&as);
r = read_bytes_to_string(a, &as, value_length, &unconsumed);
- tar_flush_unconsumed(a, &unconsumed);
+ if (tar_flush_unconsumed(a, &unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
if (r < ARCHIVE_OK) {
archive_string_free(&as);
*result = 0;
@@ -2940,7 +2962,9 @@ header_gnutar(struct archive_read *a, struct tar *tar,
/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_gnutar *)h;
const char *existing_pathname = archive_entry_pathname(entry);
- if (existing_pathname == NULL || existing_pathname[0] == '\0') {
+ const wchar_t *existing_wcs_pathname = archive_entry_pathname_w(entry);
+ if ((existing_pathname == NULL || existing_pathname[0] == '\0')
+ && (existing_wcs_pathname == NULL || existing_wcs_pathname[0] == L'\0')) {
if (archive_entry_copy_pathname_l(entry,
header->name, sizeof(header->name), tar->sconv) != 0) {
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
@@ -3093,7 +3117,9 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
return (ARCHIVE_OK);
do {
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
data = __archive_read_ahead(a, 512, &bytes_read);
if (data == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -3283,7 +3309,9 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed)
return (ARCHIVE_FATAL);
}
/* Skip rest of block... */
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
bytes_read = tar->entry_bytes_remaining - remaining;
to_skip = 0x1ff & -bytes_read;
/* Fail if tar->entry_bytes_remaing would get negative */
@@ -3509,7 +3537,9 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
const char *s;
void *p;
- tar_flush_unconsumed(a, unconsumed);
+ if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
t = __archive_read_ahead(a, 1, &bytes_read);
if (bytes_read <= 0 || t == NULL)
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_warc.c b/contrib/libarchive/libarchive/archive_read_support_format_warc.c
index 696f959c341d..d8f188cf0b44 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_warc.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_warc.c
@@ -405,7 +405,7 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
/* it's our lucky day, no work, we can leave early */
*buf = NULL;
*bsz = 0U;
- *off = w->cntoff + 4U/*for \r\n\r\n separator*/;
+ *off = w->cntoff;
w->unconsumed = 0U;
return (ARCHIVE_EOF);
}
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libarchive/libarchive/archive_read_support_format_xar.c
index b4e1192ef771..36b5ab3ae04c 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_xar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_xar.c
@@ -930,7 +930,7 @@ xar_read_data(struct archive_read *a,
abort_read_data:
*buff = NULL;
*size = 0;
- *offset = xar->total;
+ *offset = (int64_t)xar->entry_total;
return (r);
}
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c
index daf51933d687..9abd55709e3f 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c
@@ -3015,8 +3015,8 @@ init_WinZip_AES_decryption(struct archive_read *a)
p, salt_len, 1000, derived_key, key_len * 2 + 2);
if (r != 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Decryption is unsupported due to lack of "
- "crypto library");
+ r == CRYPTOR_STUB_FUNCTION ? "Decryption is unsupported due "
+ "to lack of crypto library" : "Failed to process passphrase");
return (ARCHIVE_FAILED);
}
diff --git a/contrib/libarchive/libarchive/archive_string.c b/contrib/libarchive/libarchive/archive_string.c
index 7437715f9122..3bb978335eb8 100644
--- a/contrib/libarchive/libarchive/archive_string.c
+++ b/contrib/libarchive/libarchive/archive_string.c
@@ -2015,7 +2015,7 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
/* We must allocate memory even if there is no data for conversion
* or copy. This simulates archive_string_append behavior. */
if (length == 0) {
- int tn = 1;
+ size_t tn = 1;
if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
tn = 2;
if (archive_string_ensure(as, as->length + tn) == NULL)
@@ -2752,7 +2752,8 @@ archive_string_append_unicode(struct archive_string *as, const void *_p,
char *p, *endp;
uint32_t uc;
size_t w;
- int n, ret = 0, ts, tm;
+ size_t ts, tm;
+ int n, ret = 0;
int (*parse)(uint32_t *, const char *, size_t);
size_t (*unparse)(char *, size_t, uint32_t);
diff --git a/contrib/libarchive/libarchive/archive_string_sprintf.c b/contrib/libarchive/libarchive/archive_string_sprintf.c
index 1c5910e0b2d3..69b0cdcd83d5 100644
--- a/contrib/libarchive/libarchive/archive_string_sprintf.c
+++ b/contrib/libarchive/libarchive/archive_string_sprintf.c
@@ -146,7 +146,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
case 'z': s = va_arg(ap, ssize_t); break;
default: s = va_arg(ap, int); break;
}
- append_int(as, s, 10);
+ append_int(as, s, 10);
break;
case 's':
switch(long_flag) {
diff --git a/contrib/libarchive/libarchive/archive_util.c b/contrib/libarchive/libarchive/archive_util.c
index 900abd0c3c62..d048bbc94650 100644
--- a/contrib/libarchive/libarchive/archive_util.c
+++ b/contrib/libarchive/libarchive/archive_util.c
@@ -445,11 +445,39 @@ __archive_mkstemp(wchar_t *template)
#else
static int
-get_tempdir(struct archive_string *temppath)
+__archive_issetugid(void)
{
- const char *tmp;
+#ifdef HAVE_ISSETUGID
+ return (issetugid());
+#elif HAVE_GETRESUID
+ uid_t ruid, euid, suid;
+ gid_t rgid, egid, sgid;
+ if (getresuid(&ruid, &euid, &suid) != 0)
+ return (-1);
+ if (ruid != euid || ruid != suid)
+ return (1);
+ if (getresgid(&ruid, &egid, &sgid) != 0)
+ return (-1);
+ if (rgid != egid || rgid != sgid)
+ return (1);
+#elif HAVE_GETEUID
+ if (geteuid() != getuid())
+ return (1);
+#if HAVE_GETEGID
+ if (getegid() != getgid())
+ return (1);
+#endif
+#endif
+ return (0);
+}
+
+int
+__archive_get_tempdir(struct archive_string *temppath)
+{
+ const char *tmp = NULL;
- tmp = getenv("TMPDIR");
+ if (__archive_issetugid() == 0)
+ tmp = getenv("TMPDIR");
if (tmp == NULL)
#ifdef _PATH_TMP
tmp = _PATH_TMP;
@@ -476,7 +504,7 @@ __archive_mktemp(const char *tmpdir)
archive_string_init(&temp_name);
if (tmpdir == NULL) {
- if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
goto exit_tmpfile;
} else {
archive_strcpy(&temp_name, tmpdir);
@@ -538,7 +566,7 @@ __archive_mktempx(const char *tmpdir, char *template)
if (template == NULL) {
archive_string_init(&temp_name);
if (tmpdir == NULL) {
- if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
goto exit_tmpfile;
} else
archive_strcpy(&temp_name, tmpdir);
diff --git a/contrib/libarchive/libarchive/archive_write.c b/contrib/libarchive/libarchive/archive_write.c
index a8e7b63b5bfe..9b9cb196f0f9 100644
--- a/contrib/libarchive/libarchive/archive_write.c
+++ b/contrib/libarchive/libarchive/archive_write.c
@@ -360,7 +360,6 @@ archive_write_client_open(struct archive_write_filter *f)
struct archive_none *state;
void *buffer;
size_t buffer_size;
- int ret;
f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
f->bytes_in_last_block =
@@ -385,13 +384,7 @@ archive_write_client_open(struct archive_write_filter *f)
if (a->client_opener == NULL)
return (ARCHIVE_OK);
- ret = a->client_opener(f->archive, a->client_data);
- if (ret != ARCHIVE_OK) {
- free(state->buffer);
- free(state);
- f->data = NULL;
- }
- return (ret);
+ return (a->client_opener(f->archive, a->client_data));
}
static int
@@ -480,6 +473,7 @@ static int
archive_write_client_free(struct archive_write_filter *f)
{
struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state = (struct archive_none *)f->data;
if (a->client_freer)
(*a->client_freer)(&a->archive, a->client_data);
@@ -492,6 +486,13 @@ archive_write_client_free(struct archive_write_filter *f)
a->passphrase = NULL;
}
+ /* Free state. */
+ if (state != NULL) {
+ free(state->buffer);
+ free(state);
+ f->data = NULL;
+ }
+
return (ARCHIVE_OK);
}
@@ -548,8 +549,6 @@ archive_write_client_close(struct archive_write_filter *f)
}
if (a->client_closer)
(*a->client_closer)(&a->archive, a->client_data);
- free(state->buffer);
- free(state);
/* Clear the close handler myself not to be called again. */
f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
@@ -807,7 +806,10 @@ _archive_write_finish_entry(struct archive *_a)
if (a->archive.state & ARCHIVE_STATE_DATA
&& a->format_finish_entry != NULL)
ret = (a->format_finish_entry)(a);
- a->archive.state = ARCHIVE_STATE_HEADER;
+ if (ret == ARCHIVE_FATAL)
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ else
+ a->archive.state = ARCHIVE_STATE_HEADER;
return (ret);
}
@@ -819,6 +821,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s)
{
struct archive_write *a = (struct archive_write *)_a;
const size_t max_write = INT_MAX;
+ int ret;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
@@ -826,7 +829,10 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s)
if (s > max_write)
s = max_write;
archive_clear_error(&a->archive);
- return ((a->format_write_data)(a, buff, s));
+ ret = (a->format_write_data)(a, buff, s);
+ if (ret == ARCHIVE_FATAL)
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ret);
}
static struct archive_write_filter *
diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
index 0726f08936ec..2434528d5133 100644
--- a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
+++ b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
@@ -281,6 +281,10 @@ static int
archive_compressor_bzip2_free(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
+
+ /* May already have been called, but not necessarily. */
+ (void)BZ2_bzCompressEnd(&(data->stream));
+
free(data->compressed);
free(data);
f->data = NULL;
diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c b/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
index 5ef43c1936ed..b09e669b753d 100644
--- a/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
+++ b/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
@@ -191,7 +191,8 @@ static int
archive_compressor_gzip_open(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret;
+ int ret = ARCHIVE_OK;
+ int init_success;
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
@@ -221,44 +222,66 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
data->compressed[0] = 0x1f; /* GZip signature bytes */
data->compressed[1] = 0x8b;
data->compressed[2] = 0x08; /* "Deflate" compression */
- data->compressed[3] = data->original_filename == NULL ? 0 : 0x8;
+ data->compressed[3] = 0x00; /* Flags */
if (data->timestamp >= 0) {
time_t t = time(NULL);
data->compressed[4] = (uint8_t)(t)&0xff; /* Timestamp */
data->compressed[5] = (uint8_t)(t>>8)&0xff;
data->compressed[6] = (uint8_t)(t>>16)&0xff;
data->compressed[7] = (uint8_t)(t>>24)&0xff;
- } else
+ } else {
memset(&data->compressed[4], 0, 4);
- if (data->compression_level == 9)
- data->compressed[8] = 2;
- else if(data->compression_level == 1)
- data->compressed[8] = 4;
- else
- data->compressed[8] = 0;
+ }
+ if (data->compression_level == 9) {
+ data->compressed[8] = 2;
+ } else if(data->compression_level == 1) {
+ data->compressed[8] = 4;
+ } else {
+ data->compressed[8] = 0;
+ }
data->compressed[9] = 3; /* OS=Unix */
data->stream.next_out += 10;
data->stream.avail_out -= 10;
if (data->original_filename != NULL) {
- strcpy((char*)data->compressed + 10, data->original_filename);
- data->stream.next_out += strlen(data->original_filename) + 1;
- data->stream.avail_out -= strlen(data->original_filename) + 1;
+ /* Limit "original filename" to 32k or the
+ * remaining space in the buffer, whichever is smaller.
+ */
+ int ofn_length = strlen(data->original_filename);
+ int ofn_max_length = 32768;
+ int ofn_space_available = data->compressed
+ + data->compressed_buffer_size
+ - data->stream.next_out
+ - 1;
+ if (ofn_max_length > ofn_space_available) {
+ ofn_max_length = ofn_space_available;
+ }
+ if (ofn_length < ofn_max_length) {
+ data->compressed[3] |= 0x8;
+ strcpy((char*)data->compressed + 10,
+ data->original_filename);
+ data->stream.next_out += ofn_length + 1;
+ data->stream.avail_out -= ofn_length + 1;
+ } else {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Gzip 'Original Filename' ignored because it is too long");
+ ret = ARCHIVE_WARN;
+ }
}
f->write = archive_compressor_gzip_write;
/* Initialize compression library. */
- ret = deflateInit2(&(data->stream),
+ init_success = deflateInit2(&(data->stream),
data->compression_level,
Z_DEFLATED,
-15 /* < 0 to suppress zlib header */,
8,
Z_DEFAULT_STRATEGY);
- if (ret == Z_OK) {
+ if (init_success == Z_OK) {
f->data = data;
- return (ARCHIVE_OK);
+ return (ret);
}
/* Library setup failed: clean up. */
@@ -266,7 +289,7 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
"initializing compression library");
/* Override the error message if we know what really went wrong. */
- switch (ret) {
+ switch (init_success) {
case Z_STREAM_ERROR:
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
"Internal error initializing "
diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_program.c b/contrib/libarchive/libarchive/archive_write_add_filter_program.c
index c661cc7f412f..f12db3373883 100644
--- a/contrib/libarchive/libarchive/archive_write_add_filter_program.c
+++ b/contrib/libarchive/libarchive/archive_write_add_filter_program.c
@@ -330,6 +330,7 @@ __archive_write_program_close(struct archive_write_filter *f,
struct archive_write_program_data *data)
{
int ret, status;
+ pid_t pid;
ssize_t bytes_read;
if (data->child == 0)
@@ -373,14 +374,12 @@ cleanup:
close(data->child_stdin);
if (data->child_stdout != -1)
close(data->child_stdout);
- while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
- continue;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- CloseHandle(data->child);
-#endif
+ do {
+ pid = waitpid(data->child, &status, 0);
+ } while (pid == -1 && errno == EINTR);
data->child = 0;
- if (status != 0) {
+ if (pid < 0 || status != 0) {
archive_set_error(f->archive, EIO,
"Error closing program: %s", data->program_name);
ret = ARCHIVE_FATAL;
diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
index c0a6e5a37a66..d4752c247157 100644
--- a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
+++ b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
@@ -391,6 +391,8 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
+ ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_checksumFlag, 1);
+
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
#endif
diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c
index 1bbfd7a3d779..aeb27e1270ad 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c
@@ -2204,7 +2204,7 @@ restore_entry(struct archive_write_disk *a)
(void)clear_nochange_fflags(a);
if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
- S_ISREG(a->st.st_mode)) {
+ S_ISREG(a->mode)) {
/* Use a temporary file to extract */
if ((a->fd = la_mktemp(a)) == -1) {
archive_set_error(&a->archive, errno,
@@ -2559,9 +2559,9 @@ _archive_write_disk_close(struct archive *_a)
* for directories. For other file types
* we need to verify via fstat() or lstat()
*/
- if (fd == -1 || p->filetype != AE_IFDIR) {
+ if (fd < 0 || p->filetype != AE_IFDIR) {
#if HAVE_FSTAT
- if (fd > 0 && (
+ if (fd >= 0 && (
fstat(fd, &st) != 0 ||
la_verify_filetype(st.st_mode,
p->filetype) == 0)) {
@@ -3930,10 +3930,14 @@ clear_nochange_fflags(struct archive_write_disk *a)
#ifdef UF_APPEND
| UF_APPEND
#endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+ | FS_APPEND_FL
+#elif defined(EXT2_APPEND_FL)
| EXT2_APPEND_FL
#endif
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+ | FS_IMMUTABLE_FL
+#elif defined(EXT2_IMMUTABLE_FL)
| EXT2_IMMUTABLE_FL
#endif
;
@@ -4437,7 +4441,7 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
*/
fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC);
__archive_ensure_cloexec_flag(fd);
- if (fd == -1) {
+ if (fd < 0) {
archive_set_error(&a->archive, errno,
"Failed to open a restoring file");
ret = ARCHIVE_WARN;
diff --git a/contrib/libarchive/libarchive/archive_write_open_fd.c b/contrib/libarchive/libarchive/archive_write_open_fd.c
index 8a3f68d0699d..ba034ed92f8a 100644
--- a/contrib/libarchive/libarchive/archive_write_open_fd.c
+++ b/contrib/libarchive/libarchive/archive_write_open_fd.c
@@ -122,7 +122,7 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
mine = (struct write_fd_data *)client_data;
for (;;) {
bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
+ if (bytesWritten < 0) {
if (errno == EINTR)
continue;
archive_set_error(a, errno, "Write error");
diff --git a/contrib/libarchive/libarchive/archive_write_open_file.c b/contrib/libarchive/libarchive/archive_write_open_file.c
index 4c6ebfb2269d..0b310f3da83b 100644
--- a/contrib/libarchive/libarchive/archive_write_open_file.c
+++ b/contrib/libarchive/libarchive/archive_write_open_file.c
@@ -85,16 +85,12 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
size_t bytesWritten;
mine = client_data;
- for (;;) {
- bytesWritten = fwrite(buff, 1, length, mine->f);
- if (bytesWritten <= 0) {
- if (errno == EINTR)
- continue;
- archive_set_error(a, errno, "Write error");
- return (-1);
- }
- return (bytesWritten);
+ bytesWritten = fwrite(buff, 1, length, mine->f);
+ if (bytesWritten != length) {
+ archive_set_error(a, errno, "Write error");
+ return (-1);
}
+ return (bytesWritten);
}
static int
diff --git a/contrib/libarchive/libarchive/archive_write_open_filename.c b/contrib/libarchive/libarchive/archive_write_open_filename.c
index 34209426558c..7d0f9bde1dbb 100644
--- a/contrib/libarchive/libarchive/archive_write_open_filename.c
+++ b/contrib/libarchive/libarchive/archive_write_open_filename.c
@@ -108,6 +108,7 @@ open_filename(struct archive *a, int mbs_fn, const void *filename)
else
r = archive_mstring_copy_wcs(&mine->filename, filename);
if (r < 0) {
+ free(mine);
if (errno == ENOMEM) {
archive_set_error(a, ENOMEM, "No memory");
return (ARCHIVE_FATAL);
@@ -227,7 +228,7 @@ file_write(struct archive *a, void *client_data, const void *buff,
mine = (struct write_file_data *)client_data;
for (;;) {
bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
+ if (bytesWritten < 0) {
if (errno == EINTR)
continue;
archive_set_error(a, errno, "Write error");
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c
index c2bce5975a46..175285da13be 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c
@@ -686,7 +686,7 @@ write_to_temp(struct archive_write *a, const void *buff, size_t s)
ws = write(zip->temp_fd, p, s);
if (ws < 0) {
archive_set_error(&(a->archive), errno,
- "fwrite function failed");
+ "write function failed");
return (ARCHIVE_FATAL);
}
s -= ws;
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_mtree.c b/contrib/libarchive/libarchive/archive_write_set_format_mtree.c
index 02fbb2d2f555..8131574c8da2 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_mtree.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_mtree.c
@@ -1927,7 +1927,7 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
}
/*
- * Find out the position which points the last position of
+ * Find out the position which points to the last position of
* path separator('/').
*/
slash = NULL;
@@ -2024,7 +2024,7 @@ mtree_entry_add_child_tail(struct mtree_entry *parent,
}
/*
- * Find a entry from a parent entry with the name.
+ * Find an entry from a parent entry with given name.
*/
static struct mtree_entry *
mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
@@ -2148,10 +2148,10 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
/* Find next sub directory. */
if (!np->dir_info) {
- /* NOT Directory! */
+ /* NOT a directory! */
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
- "`%s' is not directory, we cannot insert `%s' ",
+ "`%s' is not a directory, we cannot insert `%s' ",
np->pathname.s, file->pathname.s);
return (ARCHIVE_FAILED);
}
@@ -2243,10 +2243,7 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
}
same_entry:
- /*
- * We have already has the entry the filename of which is
- * the same.
- */
+ /* We already have an entry with same filename. */
r = mtree_entry_exchange_same_entry(a, np, file);
if (r < ARCHIVE_WARN)
return (r);
@@ -2264,13 +2261,13 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Found duplicate entries `%s' and its file type is "
- "different",
+ "Found duplicate entries for `%s' with "
+ "differing file types.",
np->pathname.s);
return (ARCHIVE_FAILED);
}
- /* Update the existent mtree entry's attributes by the new one's. */
+ /* Update the existing mtree entry's attributes by the new one's. */
archive_string_empty(&np->symlink);
archive_string_concat(&np->symlink, &file->symlink);
archive_string_empty(&np->uname);
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_xar.c b/contrib/libarchive/libarchive/archive_write_set_format_xar.c
index 3775e9f5819a..9921f1032be5 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_xar.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_xar.c
@@ -689,7 +689,7 @@ write_to_temp(struct archive_write *a, const void *buff, size_t s)
ws = write(xar->temp_fd, p, s);
if (ws < 0) {
archive_set_error(&(a->archive), errno,
- "fwrite function failed");
+ "write function failed");
return (ARCHIVE_FATAL);
}
s -= ws;
@@ -3418,8 +3418,8 @@ static int
xml_writer_get_final_content_and_length(struct xml_writer *ctx,
const char **out, size_t *size)
{
- *out = (const char*)ctx->bp->content;
- *size = (size_t)ctx->bp->use;
+ *out = (const char*)xmlBufferContent(ctx->bp);
+ *size = (size_t)xmlBufferLength(ctx->bp);
return (0);
}
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_zip.c b/contrib/libarchive/libarchive/archive_write_set_format_zip.c
index 3630b9f2b3a3..19121b519148 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_zip.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_zip.c
@@ -1856,7 +1856,10 @@ archive_write_zip_finish_entry(struct archive_write *a)
}
ret = __archive_write_output(a, zip->buf, remainder);
if (ret != ARCHIVE_OK)
+ {
+ deflateEnd(&zip->stream.deflate);
return (ret);
+ }
zip->entry_compressed_written += remainder;
zip->written_bytes += remainder;
zip->stream.deflate.next_out = zip->buf;
@@ -1898,7 +1901,10 @@ archive_write_zip_finish_entry(struct archive_write *a)
}
ret = __archive_write_output(a, zip->buf, remainder);
if (ret != ARCHIVE_OK)
+ {
+ BZ2_bzCompressEnd(&zip->stream.bzip2);
return (ret);
+ }
zip->entry_compressed_written += remainder;
zip->written_bytes += remainder;
zip->stream.bzip2.next_out = (char*)zip->buf;
@@ -1940,13 +1946,17 @@ archive_write_zip_finish_entry(struct archive_write *a)
}
ret = __archive_write_output(a, zip->buf, remainder);
if (ret != ARCHIVE_OK)
+ {
+ ZSTD_freeCStream(zip->stream.zstd.context);
return (ret);
+ }
zip->entry_compressed_written += remainder;
zip->written_bytes += remainder;
- zip->stream.zstd.out.dst = zip->buf;
if (zip->stream.zstd.out.pos != zip->stream.zstd.out.size)
finishing = 0;
+ zip->stream.zstd.out.dst = zip->buf;
zip->stream.zstd.out.size = zip->len_buf;
+ zip->stream.zstd.out.pos = 0;
} while (finishing);
ZSTD_freeCStream(zip->stream.zstd.context);
break;
@@ -1984,7 +1994,10 @@ archive_write_zip_finish_entry(struct archive_write *a)
}
ret = __archive_write_output(a, zip->buf, remainder);
if (ret != ARCHIVE_OK)
+ {
+ lzma_end(&zip->stream.lzma.context);
return (ret);
+ }
zip->entry_compressed_written += remainder;
zip->written_bytes += remainder;
zip->stream.lzma.context.next_out = zip->buf;
@@ -2434,13 +2447,19 @@ init_winzip_aes_encryption(struct archive_write *a)
"Can't generate random number for encryption");
return (ARCHIVE_FATAL);
}
- archive_pbkdf2_sha1(passphrase, strlen(passphrase),
+ ret = archive_pbkdf2_sha1(passphrase, strlen(passphrase),
salt, salt_len, 1000, derived_key, key_len * 2 + 2);
+ if (ret != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ ret == CRYPTOR_STUB_FUNCTION ? "Encryption is unsupported due to "
+ "lack of crypto library" : "Failed to process passphrase");
+ return (ARCHIVE_FAILED);
+ }
ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
if (ret != 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Decryption is unsupported due to lack of crypto library");
+ "Failed to initialize AES CTR mode");
return (ARCHIVE_FAILED);
}
ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
diff --git a/contrib/libarchive/libarchive/filter_fork_posix.c b/contrib/libarchive/libarchive/filter_fork_posix.c
index c895c08e59b3..7c48519336ff 100644
--- a/contrib/libarchive/libarchive/filter_fork_posix.c
+++ b/contrib/libarchive/libarchive/filter_fork_posix.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007 Joerg Sonnenberger
- * Copyright (c) 2012 Michihiro NAKAJIMA
+ * Copyright (c) 2012 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -76,7 +76,15 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
{
pid_t child = -1;
int stdin_pipe[2], stdout_pipe[2], tmp;
+
+#if !defined(POSIX_SPAWN_CLOEXEC_DEFAULT) && \
+ (HAVE_FORK || HAVE_VFORK) && \
+ (HAVE_CLOSEFROM || HAVE_CLOSE_RANGE || defined(_SC_OPEN_MAX))
+#undef HAVE_POSIX_SPAWNP
+#endif
+
#if HAVE_POSIX_SPAWNP
+ posix_spawnattr_t attr;
posix_spawn_file_actions_t actions;
int r;
#endif
@@ -107,11 +115,21 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
#if HAVE_POSIX_SPAWNP
- r = posix_spawn_file_actions_init(&actions);
+ r = posix_spawnattr_init(&attr);
if (r != 0) {
errno = r;
goto stdout_opened;
}
+ r = posix_spawn_file_actions_init(&actions);
+ if (r != 0) {
+ errno = r;
+ goto attr_inited;
+ }
+#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
+ r = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT);
+ if (r != 0)
+ goto actions_inited;
+#endif
r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]);
if (r != 0)
goto actions_inited;
@@ -136,11 +154,12 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
if (r != 0)
goto actions_inited;
}
- r = posix_spawnp(&child, cmdline->path, &actions, NULL,
+ r = posix_spawnp(&child, cmdline->path, &actions, &attr,
cmdline->argv, NULL);
if (r != 0)
goto actions_inited;
posix_spawn_file_actions_destroy(&actions);
+ posix_spawnattr_destroy(&attr);
#else /* HAVE_POSIX_SPAWNP */
@@ -162,6 +181,16 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
_exit(254);
if (stdout_pipe[1] != 1 /* stdout */)
close(stdout_pipe[1]);
+
+#if HAVE_CLOSEFROM
+ closefrom(3);
+#elif HAVE_CLOSE_RANGE
+ close_range(3, ~0U, 0);
+#elif defined(_SC_OPEN_MAX)
+ for (int i = sysconf(_SC_OPEN_MAX); i > 3;)
+ close(--i);
+#endif
+
execvp(cmdline->path, cmdline->argv);
_exit(254);
}
@@ -183,6 +212,8 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
actions_inited:
errno = r;
posix_spawn_file_actions_destroy(&actions);
+attr_inited:
+ posix_spawnattr_destroy(&attr);
#endif
stdout_opened:
close(stdout_pipe[0]);
diff --git a/contrib/libarchive/libarchive/test/test_acl_nfs4.c b/contrib/libarchive/libarchive/test/test_acl_nfs4.c
index 98d39689df69..050c0a063654 100644
--- a/contrib/libarchive/libarchive/test/test_acl_nfs4.c
+++ b/contrib/libarchive/libarchive/test/test_acl_nfs4.c
@@ -145,6 +145,13 @@ static struct archive_test_acl_t acls_bad[] = {
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE,
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+
+ /* Multiple types */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW | ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+ ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_NFS4, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
};
DEFINE_TEST(test_acl_nfs4)
diff --git a/contrib/libarchive/libarchive/test/test_acl_posix1e.c b/contrib/libarchive/libarchive/test/test_acl_posix1e.c
index 025ef6afd102..f9b6ffeb6ab7 100644
--- a/contrib/libarchive/libarchive/test/test_acl_posix1e.c
+++ b/contrib/libarchive/libarchive/test/test_acl_posix1e.c
@@ -94,6 +94,11 @@ static struct archive_test_acl_t acls_nfs4[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+
+ /* Invalid type codes */
+ { ARCHIVE_ENTRY_ACL_TYPE_ACCESS | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
+ ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
};
DEFINE_TEST(test_acl_posix1e)
diff --git a/contrib/libarchive/libarchive/test/test_archive_parse_date.c b/contrib/libarchive/libarchive/test/test_archive_parse_date.c
index 0a70971b1da6..5251b3393999 100644
--- a/contrib/libarchive/libarchive/test/test_archive_parse_date.c
+++ b/contrib/libarchive/libarchive/test/test_archive_parse_date.c
@@ -39,6 +39,8 @@ DEFINE_TEST(test_archive_parse_date)
assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0);
assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138);
assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980);
+ assertEqualInt(get_date(now, "2038-06-01 00:01:02 UTC"),
+ sizeof(time_t) <= 4 ? -1 : 2158963262);
assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000);
assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460);
assertEqualInt(get_date(now, "now - 2 hours"),
diff --git a/contrib/libarchive/libarchive/test/test_archive_string_conversion.c b/contrib/libarchive/libarchive/test/test_archive_string_conversion.c
index 12976f3e70ec..055bddc75068 100644
--- a/contrib/libarchive/libarchive/test/test_archive_string_conversion.c
+++ b/contrib/libarchive/libarchive/test/test_archive_string_conversion.c
@@ -991,6 +991,7 @@ DEFINE_TEST(test_archive_string_update_utf8_koi8)
static const char koi8_string[] = "\xD0\xD2\xC9";
static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438";
struct archive_mstring mstr;
+ struct archive *a;
int r;
memset(&mstr, 0, sizeof(mstr));
@@ -999,6 +1000,15 @@ DEFINE_TEST(test_archive_string_update_utf8_koi8)
skipping("KOI8-R locale not available on this system.");
return;
}
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ archive_write_free(a);
r = archive_mstring_update_utf8(NULL, &mstr, utf8_string);
diff --git a/contrib/libarchive/libarchive/test/test_entry.c b/contrib/libarchive/libarchive/test/test_entry.c
index 9b21b83ecdfb..cff9c5c86efc 100644
--- a/contrib/libarchive/libarchive/test/test_entry.c
+++ b/contrib/libarchive/libarchive/test/test_entry.c
@@ -880,6 +880,17 @@ DEFINE_TEST(test_entry)
if (pst == NULL)
return;
assertEqualInt(pst->st_uid, 22);
+
+ /* Check behavior with large sizes. */
+ archive_entry_set_size(e, INT64_MAX - 1);
+ assert((pst = archive_entry_stat(e)) != NULL);
+ if (pst == NULL)
+ return;
+ if (sizeof(pst->st_size) < sizeof(int64_t))
+ assertEqualInt(pst->st_size, 0);
+ else
+ assertEqualInt(pst->st_size, INT64_MAX - 1);
+
/* We don't need to check high-res fields here. */
/*
diff --git a/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c b/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c
index 0042a0511d5a..51b614b6c023 100644
--- a/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c
+++ b/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c
@@ -29,8 +29,8 @@ DEFINE_TEST(test_read_filter_gzip_recursive)
const char *name = "test_read_filter_gzip_recursive.gz";
struct archive *a;
- if (!canGzip()) {
- skipping("gzip not available");
+ if (archive_zlib_version() == NULL) {
+ skipping("zlib not available");
return;
}
diff --git a/contrib/libarchive/libarchive/test/test_read_format_7zip.c b/contrib/libarchive/libarchive/test/test_read_format_7zip.c
index ad10ef06bbc5..3236fee2c9d3 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_7zip.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_7zip.c
@@ -1285,19 +1285,26 @@ DEFINE_TEST(test_read_format_7zip_sfx_pe)
const char test_txt[] = "123";
int size = sizeof(test_txt) - 1;
- extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_filter_all(a));
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_open_filename(a, reffile, bs));
- assertA(0 == archive_read_next_header(a, &ae));
- assertEqualString("test.txt.txt", archive_entry_pathname(ae));
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+ skipping(
+ "7zip:lzma decoding is not supported on this platform");
+ } else {
+ extract_reference_file(reffile);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_filename(a, reffile, bs));
- assertA(size == archive_read_data(a, buff, size));
- assertEqualMem(buff, test_txt, size);
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt.txt", archive_entry_pathname(ae));
+
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ }
- assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
@@ -1316,19 +1323,26 @@ DEFINE_TEST(test_read_format_7zip_sfx_modified_pe)
const char test_txt[] = "123";
int size = sizeof(test_txt) - 1;
- extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_filter_all(a));
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_open_filename(a, reffile, bs));
- assertA(0 == archive_read_next_header(a, &ae));
- assertEqualString("test.txt.txt", archive_entry_pathname(ae));
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+ skipping(
+ "7zip:lzma decoding is not supported on this platform");
+ } else {
+ extract_reference_file(reffile);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_filename(a, reffile, bs));
+
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt.txt", archive_entry_pathname(ae));
+
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
- assertA(size == archive_read_data(a, buff, size));
- assertEqualMem(buff, test_txt, size);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ }
- assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
@@ -1346,20 +1360,27 @@ DEFINE_TEST(test_read_format_7zip_sfx_elf)
const char test_txt[] = "123";
int size = sizeof(test_txt) - 1;
- extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_filter_all(a));
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_open_filename(a, reffile, bs));
- assertA(0 == archive_read_next_header(a, &ae));
- assertEqualString("test.txt.txt", archive_entry_pathname(ae));
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+ skipping(
+ "7zip:lzma decoding is not supported on this platform");
+ } else {
+ extract_reference_file(reffile);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_filename(a, reffile, bs));
+
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt.txt", archive_entry_pathname(ae));
- assertA(size == archive_read_data(a, buff, size));
- assertEqualMem(buff, test_txt, size);
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_extract_second)
@@ -1597,9 +1618,9 @@ DEFINE_TEST(test_read_format_7zip_lzma2_powerpc)
assert((a = archive_read_new()) != NULL);
- if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) {
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping(
- "7zip:deflate decoding is not supported on this platform");
+ "7zip:lzma decoding is not supported on this platform");
} else {
test_powerpc_filter("test_read_format_7zip_lzma2_powerpc.7z");
}
diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5.c b/contrib/libarchive/libarchive/test/test_read_format_rar5.c
index fd233277bc1b..6ab0d236a1ed 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_rar5.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_rar5.c
@@ -1111,6 +1111,18 @@ DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream)
EPILOGUE();
}
+DEFINE_TEST(test_read_format_rar5_nonempty_dir_data)
+{
+ PROLOGUE("test_read_format_rar5_dirdata.rar");
+
+ /* This archive is invalid. It declares a directory entry with nonzero
+ data size. */
+
+ assertA(archive_read_next_header(a, &ae) == ARCHIVE_FATAL);
+
+ EPILOGUE();
+}
+
DEFINE_TEST(test_read_format_rar5_fileattr)
{
unsigned long set, clear, flag;
@@ -1428,3 +1440,57 @@ DEFINE_TEST(test_read_format_rar5_data_ready_pointer_leak)
EPILOGUE();
}
+
+DEFINE_TEST(test_read_format_rar5_only_crypt_exfld)
+{
+ /* GH #2711 */
+
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_only_crypt_exfld.rar");
+
+ /* The reader should allow iteration through files, but should fail
+ during data extraction. */
+
+ assertA(archive_read_next_header(a, &ae) == ARCHIVE_OK);
+ assertA(archive_read_data(a, buf, sizeof(buf)) == ARCHIVE_FATAL);
+
+ /* The reader should also provide a valid error message. */
+ assertA(archive_error_string(a) != NULL);
+
+ EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_only_unsupported_exfld)
+{
+ /* GH #2711 */
+
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_unsupported_exfld.rar");
+
+ /* The reader should allow iteration through files, and it should
+ succeed with data extraction. */
+
+ assertA(archive_read_next_header(a, &ae) == ARCHIVE_OK);
+
+ /* 48 is the expected number of bytes that should be extracted */
+ assertA(archive_read_data(a, buf, sizeof(buf)) == 48);
+
+ EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_invalidhash_and_validhtime_exfld)
+{
+ /* GH #2711 */
+
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_invalid_hash_valid_htime_exfld.rar");
+
+ /* The reader should report an error when trying to process this data.
+ Returning EOF here means that the reader has failed to identify
+ malformed structure. */
+
+ assertA(archive_read_next_header(a, &ae) < 0);
+ assertA(archive_read_data(a, buf, sizeof(buf)) < 0);
+
+ EPILOGUE();
+}
diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu
new file mode 100644
index 000000000000..c7928f344a80
--- /dev/null
+++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu
@@ -0,0 +1,6 @@
+begin 644 -
+M4F%R(1H'`0`BD'[;,`$%,#8P`0&`@("``B?GD;$U`@(+@X``"_C5%:2#``(`
+M`#"``S`P,#`P,#`P,#!);S#6KA',@]:N$?*IN;YV[8"1S>?4^`,#`R,#`P,#
+-`P,#1)'C@XX*4`O.^P``
+`
+end
diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu
new file mode 100644
index 000000000000..399acd814ae4
--- /dev/null
+++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu
@@ -0,0 +1,6 @@
+begin 644 -
+M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`#^T/5L)`(###$$,>V#`D840I@``0AF
+M:6QE+G1X=`@"OX0]``$"`P(#`&EN=F%L:60@2$%32"!E>'1R82P@86YD(&QA
+>=&5R(&$@=F%L:60@2%1)344@97AT<F$@/=^&`@4$
+`
+end
diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu
new file mode 100644
index 000000000000..4f9faf350c11
--- /dev/null
+++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu
@@ -0,0 +1,7 @@
+begin 644 -
+M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`"!0_"Y/0(#)2X$+NV#`IB>)!,``0AF
+M:6QE+G1X="0!```&``````````````````````````````````````````!R
+M87(U('-T;W)E9"!F:6QE('=I=&@@;VYL>2!A($-265!4(&5X=')A(&9I96QD
+'(#W?A@(%!```
+`
+end
diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu
new file mode 100644
index 000000000000..16b456bf4873
--- /dev/null
+++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu
@@ -0,0 +1,6 @@
+begin 644 -
+M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`#>[JDS)@(##C`$,.V#`BX6Z[0``0AF
+M:6QE+G1X=`W_____#WA6-!(`````<F%R-2!S=&]R960@9FEL92!W:71H(&%N
+?('5N<W5P<&]R=&5D(&5X=')A(&9I96QD(#W?A@(%!```
+`
+end
diff --git a/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c
new file mode 100644
index 000000000000..d110553acfaf
--- /dev/null
+++ b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2025 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_read_format_tar_V_negative_size)
+{
+ /*
+ * An archive that contains a `V` volume header with a negative body size
+ *
+ * This used to lead to an infinite loop: the tar reader would "advance"
+ * by the size of the body to skip it, which would in this case end up
+ * reversing back to the beginning of the same header.
+ */
+ struct archive_entry *ae;
+ struct archive *a;
+ const char *refname = "test_read_format_tar_V_negative_size.tar";
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
diff --git a/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu
new file mode 100644
index 000000000000..230d710c8f8f
--- /dev/null
+++ b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu
@@ -0,0 +1,20 @@
+Tar archive with a single `V` header that has a negative size.
+This used to result in an infinite loop -- the tar reader would
+"advance" by the size of the header, which in this case just backed
+up to re-read the same header again.
+
+begin 644 test_read_format_tar_V_negative_size.tar
+M`#(VXP```````````````````-Z;@"E&LOX^\@````````````!7````'```
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````#___\````````@````
+M````````````````````````````5H%ZL#X]SH\-``":SN#[C4;Z5OOW-&']
+M?HHQ%WRG?Z$Q>^E#_1.OY96VEI*Z<U[)$TR502_;F$;9FU"/F'!`V:0`````
+M`````````````````````````````````````````````````````0``````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````0``````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/contrib/libarchive/libarchive/test/test_read_set_format.c b/contrib/libarchive/libarchive/test/test_read_set_format.c
index c760de0056d3..615dd8ae8022 100644
--- a/contrib/libarchive/libarchive/test/test_read_set_format.c
+++ b/contrib/libarchive/libarchive/test/test_read_set_format.c
@@ -138,7 +138,10 @@ DEFINE_TEST(test_read_append_filter)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
- assertEqualIntA(a, ARCHIVE_OK, r);
+ if (r == ARCHIVE_WARN && canGzip())
+ assertEqualString(archive_error_string(a), "Using external gzip program");
+ else
+ assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualInt(ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae));
@@ -210,7 +213,7 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
/*
* If we have "bunzip2 -q", try using that.
*/
- if (!canRunCommand("bunzip2 -h")) {
+ if (!canRunCommand("bunzip2 -h", NULL)) {
skipping("Can't run bunzip2 program on this platform");
return;
}
diff --git a/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c b/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c
index 20ca0d9a7b22..7b2e4f857a75 100644
--- a/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c
+++ b/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c
@@ -268,6 +268,35 @@ DEFINE_TEST(test_write_filter_bzip2)
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
+ * Test behavior after a fatal error (triggered by giving
+ * archive_write_open_memory() a very small buffer).
+ */
+ if (!use_prog) {
+ used1 = 0;
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_add_filter_bzip2(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, 100, &used1));
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ archive_entry_set_size(ae, 4000000);
+ archive_entry_copy_pathname(ae, "file");
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, ae));
+ for (i = 0; i < 1000000; i++) {
+ r = archive_write_data(a, &i, 4);
+ if (r == ARCHIVE_FATAL)
+ break;
+ }
+ assertEqualIntA(a, ARCHIVE_FATAL, r);
+ archive_entry_free(ae);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ }
+
+ /*
* Clean up.
*/
free(data);
diff --git a/contrib/libarchive/libarchive/test/test_write_filter_gzip.c b/contrib/libarchive/libarchive/test/test_write_filter_gzip.c
index 8fbdbed09744..a6681d7618b1 100644
--- a/contrib/libarchive/libarchive/test/test_write_filter_gzip.c
+++ b/contrib/libarchive/libarchive/test/test_write_filter_gzip.c
@@ -166,9 +166,15 @@ DEFINE_TEST(test_write_filter_gzip)
assertEqualInt(rbuff[0], 0x1f);
assertEqualInt(rbuff[1], 0x8b);
assertEqualInt(rbuff[2], 0x08);
- assertEqualInt(rbuff[3], 0x08);
- assertEqualInt(rbuff[8], 2); /* RFC 1952 flag for compression level 9 */
- assertEqualString((const char*)rbuff+10, "testorgfilename");
+ /* RFC 1952 flag for compression level 9 */
+ assertEqualInt(rbuff[8], 2);
+ /* External gzip program might not save filename */
+ if (!use_prog || rbuff[3] == 0x08) {
+ assertEqualInt(rbuff[3], 0x08);
+ assertEqualString((const char*)rbuff+10, "testorgfilename");
+ } else {
+ assertEqualInt(rbuff[3], 0x00);
+ }
/* Curiously, this test fails; the test data above compresses
* better at default compression than at level 9. */
diff --git a/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c b/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c
index a148f818dcec..d0496b025b64 100644
--- a/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c
+++ b/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c
@@ -81,8 +81,11 @@ DEFINE_TEST(test_write_filter_gzip_timestamp)
archive_entry_free(ae);
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
- failure("Timestamp should be recorded");
- assert(memcmp(buff + 4, "\x00\x00\x00\x00", 4) != 0);
+ /* External gzip program might not save timestamp */
+ if (!use_prog) {
+ failure("Timestamp should be recorded");
+ assert(memcmp(buff + 4, "\x00\x00\x00\x00", 4) != 0);
+ }
/* Test2: set "gzip:!timestamp" option. */
assert((a = archive_write_new()) != NULL);
diff --git a/contrib/libarchive/libarchive_fe/err.c b/contrib/libarchive/libarchive_fe/lafe_err.c
index f6dcf44af347..b108b9b1fea7 100644
--- a/contrib/libarchive/libarchive_fe/err.c
+++ b/contrib/libarchive/libarchive_fe/lafe_err.c
@@ -36,7 +36,7 @@
#include <string.h>
#endif
-#include "err.h"
+#include "lafe_err.h"
static void lafe_vwarnc(int, const char *, va_list) __LA_PRINTFLIKE(2, 0);
diff --git a/contrib/libarchive/libarchive_fe/err.h b/contrib/libarchive/libarchive_fe/lafe_err.h
index f4a66350a669..f4a66350a669 100644
--- a/contrib/libarchive/libarchive_fe/err.h
+++ b/contrib/libarchive/libarchive_fe/lafe_err.h
diff --git a/contrib/libarchive/libarchive_fe/line_reader.c b/contrib/libarchive/libarchive_fe/line_reader.c
index 7f0429ece3cf..0af9db53c0a2 100644
--- a/contrib/libarchive/libarchive_fe/line_reader.c
+++ b/contrib/libarchive/libarchive_fe/line_reader.c
@@ -31,7 +31,7 @@
#include <stdlib.h>
#include <string.h>
-#include "err.h"
+#include "lafe_err.h"
#include "line_reader.h"
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
diff --git a/contrib/libarchive/libarchive_fe/passphrase.c b/contrib/libarchive/libarchive_fe/passphrase.c
index 527ad2d63654..1b7a50453664 100644
--- a/contrib/libarchive/libarchive_fe/passphrase.c
+++ b/contrib/libarchive/libarchive_fe/passphrase.c
@@ -61,7 +61,7 @@
#include <readpassphrase.h>
#endif
-#include "err.h"
+#include "lafe_err.h"
#include "passphrase.h"
#ifndef HAVE_READPASSPHRASE
diff --git a/contrib/libarchive/tar/bsdtar.c b/contrib/libarchive/tar/bsdtar.c
index 53ac135f0129..92e86fd6bd94 100644
--- a/contrib/libarchive/tar/bsdtar.c
+++ b/contrib/libarchive/tar/bsdtar.c
@@ -55,7 +55,7 @@
#endif
#include "bsdtar.h"
-#include "err.h"
+#include "lafe_err.h"
#if ARCHIVE_VERSION_NUMBER < 4000000 && !defined(_PATH_DEFTAPE)
// Libarchive 4.0 and later will NOT define _PATH_DEFTAPE
@@ -183,6 +183,11 @@ main(int argc, char **argv)
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
#endif
+#ifdef SIGCHLD
+ /* Do not ignore SIGCHLD. */
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &sa, NULL);
+#endif
}
#endif
diff --git a/contrib/libarchive/tar/bsdtar.h b/contrib/libarchive/tar/bsdtar.h
index 45dfeed7dce3..782d36d6f756 100644
--- a/contrib/libarchive/tar/bsdtar.h
+++ b/contrib/libarchive/tar/bsdtar.h
@@ -16,6 +16,12 @@
#define ENV_WRITER_OPTIONS "TAR_WRITER_OPTIONS"
#define IGNORE_WRONG_MODULE_NAME "__ignore_wrong_module_name__,"
+#if defined(_MSC_VER ) && (_MSC_VER < 1927 ) /* Check if compiler pre-dated Visual Studio 2019 Release 16.8 */
+#define ARCHIVE_RESTRICT
+#else
+#define ARCHIVE_RESTRICT restrict
+#endif
+
struct creation_set;
/*
* The internal state for the "bsdtar" program.
@@ -188,7 +194,7 @@ int edit_pathname(struct bsdtar *, struct archive_entry *);
void edit_mtime(struct bsdtar *, struct archive_entry *);
int need_report(void);
int pathcmp(const char *a, const char *b);
-void safe_fprintf(FILE * restrict, const char * restrict fmt, ...) __LA_PRINTF(2, 3);
+void safe_fprintf(FILE * ARCHIVE_RESTRICT, const char * ARCHIVE_RESTRICT fmt, ...) __LA_PRINTF(2, 3);
void set_chdir(struct bsdtar *, const char *newdir);
const char *tar_i64toa(int64_t);
void tar_mode_c(struct bsdtar *bsdtar);
diff --git a/contrib/libarchive/tar/cmdline.c b/contrib/libarchive/tar/cmdline.c
index c766c1a52dbb..309be312c948 100644
--- a/contrib/libarchive/tar/cmdline.c
+++ b/contrib/libarchive/tar/cmdline.c
@@ -22,7 +22,7 @@
#endif
#include "bsdtar.h"
-#include "err.h"
+#include "lafe_err.h"
/*
* Short options for tar. Please keep this sorted.
diff --git a/contrib/libarchive/tar/creation_set.c b/contrib/libarchive/tar/creation_set.c
index 6883090418b0..51f803354a5d 100644
--- a/contrib/libarchive/tar/creation_set.c
+++ b/contrib/libarchive/tar/creation_set.c
@@ -15,7 +15,7 @@
#endif
#include "bsdtar.h"
-#include "err.h"
+#include "lafe_err.h"
struct creation_set {
char *create_format;
diff --git a/contrib/libarchive/tar/read.c b/contrib/libarchive/tar/read.c
index 8563fe714f9a..7cbcfb19ff0a 100644
--- a/contrib/libarchive/tar/read.c
+++ b/contrib/libarchive/tar/read.c
@@ -57,7 +57,7 @@
#endif
#include "bsdtar.h"
-#include "err.h"
+#include "lafe_err.h"
struct progress_data {
struct bsdtar *bsdtar;
diff --git a/contrib/libarchive/tar/subst.c b/contrib/libarchive/tar/subst.c
index 5546b5f93b12..a5d644dc5a70 100644
--- a/contrib/libarchive/tar/subst.c
+++ b/contrib/libarchive/tar/subst.c
@@ -25,7 +25,7 @@
#define REG_BASIC 0
#endif
-#include "err.h"
+#include "lafe_err.h"
struct subst_rule {
struct subst_rule *next;
diff --git a/contrib/libarchive/tar/test/test_crlf_mtree.c b/contrib/libarchive/tar/test/test_crlf_mtree.c
new file mode 100644
index 000000000000..5ef8811369c1
--- /dev/null
+++ b/contrib/libarchive/tar/test/test_crlf_mtree.c
@@ -0,0 +1,74 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Arshan Khanifar <arshankhanifar@gmail.com>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_crlf_mtree)
+{
+ char *p0;
+ size_t s;
+ int r;
+ p0 = NULL;
+ char *content = "#mtree\r\n"
+ "f type=file uname=\\\r\n"
+ "root gname=root mode=0755 content=bar/foo\r\n"
+ "g type=file uname=root gname=root mode=0755 content=bar/goo\r\n";
+ char *filename = "output.tar";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char *p;
+#endif
+
+ /* an absolute path to mtree file */
+ char *mtree_file = "/METALOG.mtree";
+ char *absolute_path = malloc(strlen(testworkdir) + strlen(mtree_file) + 1);
+ strcpy(absolute_path, testworkdir);
+ strcat(absolute_path, mtree_file );
+
+ /* Create an archive using an mtree file. */
+ assertMakeFile(absolute_path, 0777, content);
+ assertMakeDir("bar", 0775);
+ assertMakeFile("bar/foo", 0777, "abc");
+ assertMakeFile("bar/goo", 0777, "abc");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ p = absolute_path;
+ while(*p != '\0') {
+ if (*p == '/')
+ *p = '\\';
+ p++;
+ }
+
+ r = systemf("%s -cf %s @%s >step1.out 2>step1.err", testprog, filename, absolute_path);
+ failure("Error invoking %s -cf %s -C bar @%s", testprog, filename, absolute_path);
+#else
+ r = systemf("%s -cf %s \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path);
+ failure("Error invoking %s -cf %s -C bar \"@%s\"", testprog, filename, absolute_path);
+#endif
+
+ assertEqualInt(r, 0);
+ assertEmptyFile("step1.out");
+ assertEmptyFile("step1.err");
+
+ /* Do validation of the constructed archive. */
+
+ p0 = slurpfile(&s, "output.tar");
+ if (!assert(p0 != NULL))
+ goto done;
+ if (!assert(s >= 2048))
+ goto done;
+ assertEqualMem(p0 + 0, "f", 2);
+ assertEqualMem(p0 + 512, "abc", 4);
+ assertEqualMem(p0 + 1024, "g", 2);
+ assertEqualMem(p0 + 1536, "abc", 4);
+done:
+ free(p0);
+ free(absolute_path);
+}
+
+
diff --git a/contrib/libarchive/tar/test/test_option_safe_writes.c b/contrib/libarchive/tar/test/test_option_safe_writes.c
index b88479bc5f35..d30b9a745927 100644
--- a/contrib/libarchive/tar/test/test_option_safe_writes.c
+++ b/contrib/libarchive/tar/test/test_option_safe_writes.c
@@ -16,11 +16,12 @@ DEFINE_TEST(test_option_safe_writes)
assertMakeFile("d", 0644, "c");
assertMakeFile("fs", 0644, "d");
assertMakeFile("ds", 0644, "e");
+ assertMakeDir("fd", 0755);
assertEqualInt(0, chdir(".."));
/* Tar files up */
assertEqualInt(0,
- systemf("%s -c -C in -f t.tar f fh d fs ds "
+ systemf("%s -c -C in -f t.tar f fh d fs ds fd "
">pack.out 2>pack.err", testprog));
/* Verify that nothing went to stdout or stderr. */
@@ -32,6 +33,7 @@ DEFINE_TEST(test_option_safe_writes)
assertEqualInt(0, chdir("out"));
assertMakeFile("f", 0644, "a");
assertMakeHardlink("fh", "f");
+ assertMakeFile("fd", 0644, "b");
assertMakeDir("d", 0755);
if (canSymlink()) {
assertMakeSymlink("fs", "f", 0);
@@ -55,4 +57,5 @@ DEFINE_TEST(test_option_safe_writes)
assertTextFileContents("c","d");
assertTextFileContents("d","fs");
assertTextFileContents("e","ds");
+ assertIsDir("fd", 0755);
}
diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c
index c99f67797562..fc5e15cb039f 100644
--- a/contrib/libarchive/tar/util.c
+++ b/contrib/libarchive/tar/util.c
@@ -41,7 +41,7 @@
#endif
#include "bsdtar.h"
-#include "err.h"
+#include "lafe_err.h"
#include "passphrase.h"
static size_t bsdtar_expand_char(char *, size_t, size_t, char);
@@ -682,6 +682,7 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
{
char tmp[100];
size_t w;
+ size_t sw;
const char *p;
const char *fmt;
time_t tim;
@@ -769,8 +770,8 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
ltime = localtime(&tim);
#endif
if (ltime)
- strftime(tmp, sizeof(tmp), fmt, ltime);
- else
+ sw = strftime(tmp, sizeof(tmp), fmt, ltime);
+ if (!ltime || !sw)
sprintf(tmp, "-- -- ----");
fprintf(out, " %s ", tmp);
safe_fprintf(out, "%s", archive_entry_pathname(entry));
diff --git a/contrib/libarchive/tar/write.c b/contrib/libarchive/tar/write.c
index 21984e980ebd..9e6c97b580b7 100644
--- a/contrib/libarchive/tar/write.c
+++ b/contrib/libarchive/tar/write.c
@@ -58,7 +58,7 @@
#endif
#include "bsdtar.h"
-#include "err.h"
+#include "lafe_err.h"
#include "line_reader.h"
#ifndef O_BINARY
@@ -111,7 +111,32 @@ seek_file(int fd, int64_t offset, int whence)
return (SetFilePointerEx((HANDLE)_get_osfhandle(fd),
distance, NULL, FILE_BEGIN) ? 1 : -1);
}
-#define open _open
+
+static int
+_open_wrap_sopen(char const *const path, int const oflag, ...)
+{
+ va_list ap;
+ int r, pmode;
+
+ pmode = 0;
+ if (oflag & _O_CREAT)
+ {
+ va_start(ap, oflag);
+ pmode = va_arg(ap, int);
+ va_end(ap);
+ }
+
+ _sopen_s(&r, path, oflag, _SH_DENYNO, pmode & 0600);
+ if (r < 0)
+ {
+ /* _sopen_s populates errno */
+ return -1;
+ }
+
+ return r;
+}
+
+#define open _open_wrap_sopen
#define close _close
#define read _read
#ifdef lseek
diff --git a/contrib/libarchive/test_utils/test_common.h b/contrib/libarchive/test_utils/test_common.h
index 064f0a6ec241..a9df300e3be8 100644
--- a/contrib/libarchive/test_utils/test_common.h
+++ b/contrib/libarchive/test_utils/test_common.h
@@ -340,8 +340,14 @@ int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
-/* Return true if this platform can run the specified command. */
-int canRunCommand(const char *);
+/* Return true if this platform can run the specified command.
+ *
+ * Result can be optionally cached with `*tested`:
+ * - 0 if not tested yet
+ * - <0 if already tested negative
+ * - >0 if already tested positive
+ */
+int canRunCommand(const char *cmd, int *tested);
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c
index fe330e5a052e..f4d443060d88 100644
--- a/contrib/libarchive/test_utils/test_main.c
+++ b/contrib/libarchive/test_utils/test_main.c
@@ -2523,167 +2523,77 @@ static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */
#else
static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */
#endif
+
/*
- * Can this platform run the bzip2 program?
+ * Can this platform run the specified command?
*/
int
-canBzip2(void)
+canRunCommand(const char *cmd, int *tested)
{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("bzip2 --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
+ int value = tested ? *tested : 0;
+ if (!value) {
+ value = systemf("%s %s", cmd, redirectArgs) ? -1 : +1;
+ if (tested)
+ *tested = value;
+ }
+ return (value > 0);
}
+#define CAN_RUN_FUNC(Program, Command) \
+ int can##Program(void) { \
+ static int tested = 0; \
+ return canRunCommand((Command), &tested); \
+ }
+
+/*
+ * Can this platform run the bzip2 program?
+ */
+CAN_RUN_FUNC(Bzip2, "bzip2 --help")
+
/*
* Can this platform run the grzip program?
*/
-int
-canGrzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("grzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Grzip, "grzip -V")
/*
* Can this platform run the gzip program?
*/
-int
-canGzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("gzip --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Gzip, "gzip --help")
/*
* Can this platform run the lrzip program?
*/
-int
-canRunCommand(const char *cmd)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("%s %s", cmd, redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-int
-canLrzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lrzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Lrzip, "lrzip -V")
/*
* Can this platform run the lz4 program?
*/
-int
-canLz4(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lz4 --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Lz4, "lz4 --help")
/*
* Can this platform run the zstd program?
*/
-int
-canZstd(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("zstd --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Zstd, "zstd --help")
/*
* Can this platform run the lzip program?
*/
-int
-canLzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzip --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Lzip, "lzip --help")
/*
* Can this platform run the lzma program?
*/
-int
-canLzma(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzma --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Lzma, "lzma --help")
/*
* Can this platform run the lzop program?
*/
-int
-canLzop(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzop --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Lzop, "lzop --help")
/*
* Can this platform run the xz program?
*/
-int
-canXz(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("xz --help %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
+CAN_RUN_FUNC(Xz, "xz --help")
/*
* Can this filesystem handle nodump flags.
@@ -4184,6 +4094,9 @@ main(int argc, char **argv)
if (testprogfile == NULL)
{
tmp2_len = strlen(testprogdir) + 1 + strlen(PROGRAM) + 1;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ tmp2_len += 4;
+#endif
if ((tmp2 = malloc(tmp2_len)) == NULL)
{
fprintf(stderr, "ERROR: Out of memory.");
@@ -4192,6 +4105,9 @@ main(int argc, char **argv)
strncpy(tmp2, testprogdir, tmp2_len);
strncat(tmp2, "/", tmp2_len);
strncat(tmp2, PROGRAM, tmp2_len);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ strncat(tmp2, ".exe", tmp2_len);
+#endif
testprogfile = tmp2;
}
diff --git a/contrib/libarchive/unzip/bsdunzip.c b/contrib/libarchive/unzip/bsdunzip.c
index 621afbeb9d6a..1b520e841690 100644
--- a/contrib/libarchive/unzip/bsdunzip.c
+++ b/contrib/libarchive/unzip/bsdunzip.c
@@ -29,6 +29,9 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
@@ -54,7 +57,7 @@
#include "bsdunzip.h"
#include "passphrase.h"
-#include "err.h"
+#include "lafe_err.h"
/* command-line options */
static int a_opt; /* convert EOL */
@@ -1187,6 +1190,16 @@ main(int argc, char *argv[])
const char *zipfile;
int nopts;
+#if defined(HAVE_SIGACTION) && defined(SIGCHLD)
+ { /* Do not ignore SIGCHLD. */
+ struct sigaction sa;
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGCHLD, &sa, NULL);
+ }
+#endif
+
lafe_setprogname(*argv, "bsdunzip");
#if HAVE_SETLOCALE
diff --git a/contrib/libarchive/unzip/cmdline.c b/contrib/libarchive/unzip/cmdline.c
index 8afddedd5ead..8e6eedd2321c 100644
--- a/contrib/libarchive/unzip/cmdline.c
+++ b/contrib/libarchive/unzip/cmdline.c
@@ -21,7 +21,7 @@
#endif
#include "bsdunzip.h"
-#include "err.h"
+#include "lafe_err.h"
/*
* Short options for bsdunzip. Please keep this sorted.
diff --git a/contrib/libarchive/unzip/test/test_C.c b/contrib/libarchive/unzip/test/test_C.c
index 66835c8406f3..d386bd61e85d 100644
--- a/contrib/libarchive/unzip/test/test_C.c
+++ b/contrib/libarchive/unzip/test/test_C.c
@@ -9,6 +9,7 @@
/* Test C arg - match case-insensitive */
DEFINE_TEST(test_C)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -19,4 +20,7 @@ DEFINE_TEST(test_C)
assertEmptyFile("test.err");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_L.c b/contrib/libarchive/unzip/test/test_L.c
index 5b004d5d5707..85b43f592542 100644
--- a/contrib/libarchive/unzip/test/test_L.c
+++ b/contrib/libarchive/unzip/test/test_L.c
@@ -9,6 +9,7 @@
/* Test L arg - make names lowercase */
DEFINE_TEST(test_L)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,4 +23,7 @@ DEFINE_TEST(test_L)
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/caps");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_P_encryption.c b/contrib/libarchive/unzip/test/test_P_encryption.c
index e2cf3cda0ebd..ed08a068811b 100644
--- a/contrib/libarchive/unzip/test/test_P_encryption.c
+++ b/contrib/libarchive/unzip/test/test_P_encryption.c
@@ -14,9 +14,13 @@ DEFINE_TEST(test_P_encryption)
extract_reference_file(reffile);
r = systemf("%s -P password %s >test.out 2>test.err", testprog, reffile);
- assertEqualInt(0, r);
- assertNonEmptyFile("test.out");
- assertEmptyFile("test.err");
+ if (r == 256) {
+ assertTextFileContents("unzip: Decryption is unsupported due to lack of crypto library\n", "test.err");
+ } else {
+ assertEqualInt(0, r);
+ assertNonEmptyFile("test.out");
+ assertEmptyFile("test.err");
- assertTextFileContents("plaintext\n", "encrypted/file.txt");
+ assertTextFileContents("plaintext\n", "encrypted/file.txt");
+ }
}
diff --git a/contrib/libarchive/unzip/test/test_basic.c b/contrib/libarchive/unzip/test/test_basic.c
index 1f37dcd416a3..3a884aa30e5d 100644
--- a/contrib/libarchive/unzip/test/test_basic.c
+++ b/contrib/libarchive/unzip/test/test_basic.c
@@ -9,6 +9,7 @@
/* This test just does a basic zip decompression */
DEFINE_TEST(test_basic)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,4 +23,7 @@ DEFINE_TEST(test_basic)
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_d.c b/contrib/libarchive/unzip/test/test_d.c
index ea67246207f2..cd7c3dfd97ad 100644
--- a/contrib/libarchive/unzip/test/test_d.c
+++ b/contrib/libarchive/unzip/test/test_d.c
@@ -9,6 +9,7 @@
/* Test d arg - extract to target dir - before zipfile argument */
DEFINE_TEST(test_d_before_zipfile)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,11 +23,15 @@ DEFINE_TEST(test_d_before_zipfile)
assertTextFileContents("contents b\n", "foobar/test_basic/b");
assertTextFileContents("contents c\n", "foobar/test_basic/c");
assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
/* Test d arg - extract to target dir - after zipfile argument */
DEFINE_TEST(test_d_after_zipfile)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -40,4 +45,7 @@ DEFINE_TEST(test_d_after_zipfile)
assertTextFileContents("contents b\n", "foobar/test_basic/b");
assertTextFileContents("contents c\n", "foobar/test_basic/c");
assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_doubledash.c b/contrib/libarchive/unzip/test/test_doubledash.c
index 4467213dbb89..db0445ec3c24 100644
--- a/contrib/libarchive/unzip/test/test_doubledash.c
+++ b/contrib/libarchive/unzip/test/test_doubledash.c
@@ -9,6 +9,7 @@
/* Test double dash arg - swallow "--" and use next argument as file name */
DEFINE_TEST(test_doubledash)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,4 +23,7 @@ DEFINE_TEST(test_doubledash)
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_glob.c b/contrib/libarchive/unzip/test/test_glob.c
index b53aa16fd85c..589ff1c55ef3 100644
--- a/contrib/libarchive/unzip/test/test_glob.c
+++ b/contrib/libarchive/unzip/test/test_glob.c
@@ -9,6 +9,7 @@
/* Test that the glob works */
DEFINE_TEST(test_glob)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,4 +23,7 @@ DEFINE_TEST(test_glob)
assertTextFileContents("contents b\n", "test_basic/b");
assertFileNotExists("test_basic/c");
assertFileNotExists("test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_j.c b/contrib/libarchive/unzip/test/test_j.c
index b87229f42e25..1fba8ca207ec 100644
--- a/contrib/libarchive/unzip/test/test_j.c
+++ b/contrib/libarchive/unzip/test/test_j.c
@@ -9,6 +9,7 @@
/* Test j arg - don't make directories */
DEFINE_TEST(test_j)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,4 +23,7 @@ DEFINE_TEST(test_j)
assertTextFileContents("contents b\n", "b");
assertTextFileContents("contents c\n", "c");
assertTextFileContents("contents CAPS\n", "CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_n.c b/contrib/libarchive/unzip/test/test_n.c
index bb75c5d7696d..a13623ce23df 100644
--- a/contrib/libarchive/unzip/test/test_n.c
+++ b/contrib/libarchive/unzip/test/test_n.c
@@ -9,6 +9,7 @@
/* Test n arg - don't overwrite existing files */
DEFINE_TEST(test_n)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -26,4 +27,7 @@ DEFINE_TEST(test_n)
assertTextFileContents("orig b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_o.c b/contrib/libarchive/unzip/test/test_o.c
index 64f946774440..8c48348c41a4 100644
--- a/contrib/libarchive/unzip/test/test_o.c
+++ b/contrib/libarchive/unzip/test/test_o.c
@@ -9,6 +9,7 @@
/* Test o arg - overwrite existing files */
DEFINE_TEST(test_o)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -25,4 +26,7 @@ DEFINE_TEST(test_o)
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_p.c b/contrib/libarchive/unzip/test/test_p.c
index 8bfffbe5dc39..13a7765463ec 100644
--- a/contrib/libarchive/unzip/test/test_p.c
+++ b/contrib/libarchive/unzip/test/test_p.c
@@ -9,6 +9,7 @@
/* Test p arg - Print to stdout */
DEFINE_TEST(test_p)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -17,4 +18,7 @@ DEFINE_TEST(test_p)
assertEqualInt(0, r);
assertTextFileContents("contents a\ncontents b\ncontents c\ncontents CAPS\n", "test.out");
assertEmptyFile("test.err");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_q.c b/contrib/libarchive/unzip/test/test_q.c
index 13222a483992..0579e8028d76 100644
--- a/contrib/libarchive/unzip/test/test_q.c
+++ b/contrib/libarchive/unzip/test/test_q.c
@@ -9,6 +9,7 @@
/* Test q arg - Quiet */
DEFINE_TEST(test_q)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,4 +23,7 @@ DEFINE_TEST(test_q)
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_singlefile.c b/contrib/libarchive/unzip/test/test_singlefile.c
index a72811f046d9..a5a35ecacc4d 100644
--- a/contrib/libarchive/unzip/test/test_singlefile.c
+++ b/contrib/libarchive/unzip/test/test_singlefile.c
@@ -9,6 +9,7 @@
/* Ensure single-file zips work */
DEFINE_TEST(test_singlefile)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_singlefile.zip";
int r;
@@ -19,4 +20,7 @@ DEFINE_TEST(test_singlefile)
assertEmptyFile("test.err");
assertTextFileContents("hello\n", "file.txt");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_t.c b/contrib/libarchive/unzip/test/test_t.c
index 55a516fc636f..7565830915c3 100644
--- a/contrib/libarchive/unzip/test/test_t.c
+++ b/contrib/libarchive/unzip/test/test_t.c
@@ -9,6 +9,7 @@
/* Test t arg - Test zip contents */
DEFINE_TEST(test_t)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -17,4 +18,7 @@ DEFINE_TEST(test_t)
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/contrib/libarchive/unzip/test/test_x.c b/contrib/libarchive/unzip/test/test_x.c
index 959beb1950df..43a2085dc5b2 100644
--- a/contrib/libarchive/unzip/test/test_x.c
+++ b/contrib/libarchive/unzip/test/test_x.c
@@ -9,6 +9,7 @@
/* Test x arg with single exclude path */
DEFINE_TEST(test_x_single)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -22,11 +23,15 @@ DEFINE_TEST(test_x_single)
assertTextFileContents("contents b\n", "test_basic/b");
assertFileNotExists("test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
/* Test x arg with multiple exclude paths */
DEFINE_TEST(test_x_multiple)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -40,11 +45,15 @@ DEFINE_TEST(test_x_multiple)
assertFileNotExists("test_basic/b");
assertFileNotExists("test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
/* Test x arg with multiple exclude paths and a d arg afterwards */
DEFINE_TEST(test_x_multiple_with_d)
{
+#ifdef HAVE_LIBZ
const char *reffile = "test_basic.zip";
int r;
@@ -58,4 +67,7 @@ DEFINE_TEST(test_x_multiple_with_d)
assertFileNotExists("foobar/test_basic/b");
assertFileNotExists("foobar/test_basic/c");
assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS");
+#else
+ skipping("zlib not available");
+#endif
}
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index 454657183c58..1a60bbef765a 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -303,8 +303,6 @@
net80211
..
netgraph
- atm
- ..
bluetooth
include
..
diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index 520b41c8b88f..f7a3b2a33703 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -835,6 +835,8 @@
..
gpt
..
+ label
+ ..
mirror
..
multipath
diff --git a/include/stdckdint.h b/include/stdckdint.h
index af3074dded89..9cb877fe8198 100644
--- a/include/stdckdint.h
+++ b/include/stdckdint.h
@@ -13,7 +13,7 @@
#if __GNUC_PREREQ__(5, 1) || __has_builtin(__builtin_add_overflow)
#define ckd_add(result, a, b) \
- (_Bool)__builtin_add_overflow((a), (b), (result))
+ __builtin_add_overflow((a), (b), (result))
#else
#define ckd_add(result, a, b) \
_Static_assert(0, "checked addition not supported")
@@ -21,7 +21,7 @@
#if __GNUC_PREREQ__(5, 1) || __has_builtin(__builtin_sub_overflow)
#define ckd_sub(result, a, b) \
- (_Bool)__builtin_sub_overflow((a), (b), (result))
+ __builtin_sub_overflow((a), (b), (result))
#else
#define ckd_sub(result, a, b) \
_Static_assert(0, "checked subtraction not supported")
@@ -29,7 +29,7 @@
#if __GNUC_PREREQ__(5, 1) || __has_builtin(__builtin_mul_overflow)
#define ckd_mul(result, a, b) \
- (_Bool)__builtin_mul_overflow((a), (b), (result))
+ __builtin_mul_overflow((a), (b), (result))
#else
#define ckd_mul(result, a, b) \
_Static_assert(0, "checked multiplication not supported")
diff --git a/krb5/include/autoconf.h b/krb5/include/autoconf.h
index ed0bf8cacc14..760aca79176b 100644
--- a/krb5/include/autoconf.h
+++ b/krb5/include/autoconf.h
@@ -691,7 +691,15 @@
#define STDC_HEADERS 1
/* Define to 1 if strerror_r returns char *. */
+#ifdef __linux__
+#include <features.h>
+#endif
+#ifdef __GLIBC__
+/* Bootstrapping on GNU/Linux */
+#define STRERROR_R_CHAR_P 1
+#else
/* #undef STRERROR_R_CHAR_P */
+#endif
/* Define if sys_errlist is defined in errno.h */
#define SYS_ERRLIST_DECLARED 1
diff --git a/lib/libarchive/tests/Makefile b/lib/libarchive/tests/Makefile
index 07c5fe24dd30..930250d974c5 100644
--- a/lib/libarchive/tests/Makefile
+++ b/lib/libarchive/tests/Makefile
@@ -185,6 +185,7 @@ TESTS_SRCS= \
test_read_format_rar_overflow.c \
test_read_format_raw.c \
test_read_format_tar.c \
+ test_read_format_tar_V_negative_size.c \
test_read_format_tar_concatenated.c \
test_read_format_tar_empty_filename.c \
test_read_format_tar_empty_pax.c \
@@ -607,6 +608,7 @@ ${PACKAGE}FILES+= test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_different_solid_window_size.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_different_window_size.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_different_winsize_on_merge.rar.uu
+${PACKAGE}FILES+= test_read_format_rar5_dirdata.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_distance_overflow.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_encrypted.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_encrypted_filenames.rar.uu
@@ -616,6 +618,7 @@ ${PACKAGE}FILES+= test_read_format_rar5_extra_field_version.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_fileattr.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_hardlink.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_invalid_dict_reference.rar.uu
+${PACKAGE}FILES+= test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_leftshift1.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_leftshift2.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part01.rar.uu
@@ -633,6 +636,7 @@ ${PACKAGE}FILES+= test_read_format_rar5_multiarchive_solid.part04.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiple_files.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiple_files_solid.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_nonempty_dir_stream.rar.uu
+${PACKAGE}FILES+= test_read_format_rar5_only_crypt_exfld.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_owner.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_readtables_overflow.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_sfx.exe.uu
@@ -642,12 +646,14 @@ ${PACKAGE}FILES+= test_read_format_rar5_stored_manyfiles.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_symlink.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_truncated_huff.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_unicode.rar.uu
+${PACKAGE}FILES+= test_read_format_rar5_unsupported_exfld.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_win32.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_window_buf_and_size_desync.rar.uu
${PACKAGE}FILES+= test_read_format_raw.bufr.uu
${PACKAGE}FILES+= test_read_format_raw.data.Z.uu
${PACKAGE}FILES+= test_read_format_raw.data.gz.uu
${PACKAGE}FILES+= test_read_format_raw.data.uu
+${PACKAGE}FILES+= test_read_format_tar_V_negative_size.tar.uu
${PACKAGE}FILES+= test_read_format_tar_concatenated.tar.uu
${PACKAGE}FILES+= test_read_format_tar_empty_filename.tar.uu
${PACKAGE}FILES+= test_read_format_tar_empty_with_gnulabel.tar.uu
diff --git a/lib/libc/inet/inet_net_ntop.c b/lib/libc/inet/inet_net_ntop.c
index 9d98dbb5ca99..30dd5c0571f2 100644
--- a/lib/libc/inet/inet_net_ntop.c
+++ b/lib/libc/inet/inet_net_ntop.c
@@ -1,20 +1,23 @@
-/*-
- * SPDX-License-Identifier: ISC
+/* $OpenBSD: inet_net_ntop.c,v 1.9 2019/07/03 03:24:04 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org>
+ * Copyright (c) 1996 by Internet Software Consortium.
*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996,1999 by Internet Software Consortium.
+ * SPDX-License-Identifier: ISC
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#include "port_before.h"
@@ -31,18 +34,10 @@
#include "port_after.h"
-#ifdef SPRINTF_CHAR
-# define SPRINTF(x) strlen(sprintf/**/x)
-#else
-# define SPRINTF(x) ((size_t)sprintf x)
-#endif
-
-static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst,
- size_t size);
-static char * inet_net_ntop_ipv6(const u_char *src, int bits, char *dst,
- size_t size);
+static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t);
+static char *inet_net_ntop_ipv6(const u_char *, int, char *, size_t);
-/*%
+/*
* char *
* inet_net_ntop(af, src, bits, dst, size)
* convert network number from network to presentation format.
@@ -66,7 +61,7 @@ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
}
}
-/*%
+/*
* static char *
* inet_net_ntop_ipv4(src, bits, dst, size)
* convert IPv4 network number from network to presentation format.
@@ -83,53 +78,63 @@ static char *
inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
{
char *odst = dst;
- char *t;
u_int m;
int b;
+ char *ep;
+ int advance;
+
+ ep = dst + size;
+ if (ep <= dst)
+ goto emsgsize;
if (bits < 0 || bits > 32) {
errno = EINVAL;
return (NULL);
}
-
if (bits == 0) {
- if (size < sizeof "0")
+ if (ep - dst < sizeof "0")
goto emsgsize;
*dst++ = '0';
- size--;
*dst = '\0';
}
/* Format whole octets. */
for (b = bits / 8; b > 0; b--) {
- if (size <= sizeof "255.")
+ if (ep - dst < sizeof "255.")
+ goto emsgsize;
+ advance = snprintf(dst, ep - dst, "%u", *src++);
+ if (advance <= 0 || advance >= ep - dst)
goto emsgsize;
- t = dst;
- dst += SPRINTF((dst, "%u", *src++));
+ dst += advance;
if (b > 1) {
+ if (dst + 1 >= ep)
+ goto emsgsize;
*dst++ = '.';
*dst = '\0';
}
- size -= (size_t)(dst - t);
}
/* Format partial octet. */
b = bits % 8;
if (b > 0) {
- if (size <= sizeof ".255")
+ if (ep - dst < sizeof ".255")
goto emsgsize;
- t = dst;
if (dst != odst)
*dst++ = '.';
m = ((1 << b) - 1) << (8 - b);
- dst += SPRINTF((dst, "%u", *src & m));
- size -= (size_t)(dst - t);
+ advance = snprintf(dst, ep - dst, "%u", *src & m);
+ if (advance <= 0 || advance >= ep - dst)
+ goto emsgsize;
+ dst += advance;
}
/* Format CIDR /width. */
- if (size <= sizeof "/32")
+ if (ep - dst < sizeof "/32")
+ goto emsgsize;
+ advance = snprintf(dst, ep - dst, "/%u", bits);
+ if (advance <= 0 || advance >= ep - dst)
goto emsgsize;
- dst += SPRINTF((dst, "/%u", bits));
+ dst += advance;
return (odst);
emsgsize:
@@ -137,132 +142,27 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
return (NULL);
}
-/*%
- * static char *
- * inet_net_ntop_ipv6(src, bits, fakebits, dst, size)
- * convert IPv6 network number from network to presentation format.
- * generates CIDR style result always. Picks the shortest representation
- * unless the IP is really IPv4.
- * always prints specified number of bits (bits).
- * return:
- * pointer to dst, or NULL if an error occurred (check errno).
- * note:
- * network byte order assumed. this means 192.5.5.240/28 has
- * 0b11110000 in its fourth octet.
- * author:
- * Vadim Kogan (UCB), June 2001
- * Original version (IPv4) by Paul Vixie (ISC), July 1996
- */
-
static char *
-inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
- u_int m;
- int b;
- int p;
- int zero_s, zero_l, tmp_zero_s, tmp_zero_l;
- int i;
- int is_ipv4 = 0;
- unsigned char inbuf[16];
- char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
- char *cp;
- int words;
- u_char *s;
+inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
+{
+ int ret;
+ char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")];
if (bits < 0 || bits > 128) {
errno = EINVAL;
return (NULL);
}
- cp = outbuf;
-
- if (bits == 0) {
- *cp++ = ':';
- *cp++ = ':';
- *cp = '\0';
- } else {
- /* Copy src to private buffer. Zero host part. */
- p = (bits + 7) / 8;
- memcpy(inbuf, src, p);
- memset(inbuf + p, 0, 16 - p);
- b = bits % 8;
- if (b != 0) {
- m = ~0 << (8 - b);
- inbuf[p-1] &= m;
- }
-
- s = inbuf;
-
- /* how many words need to be displayed in output */
- words = (bits + 15) / 16;
- if (words == 1)
- words = 2;
-
- /* Find the longest substring of zero's */
- zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
- for (i = 0; i < (words * 2); i += 2) {
- if ((s[i] | s[i+1]) == 0) {
- if (tmp_zero_l == 0)
- tmp_zero_s = i / 2;
- tmp_zero_l++;
- } else {
- if (tmp_zero_l && zero_l < tmp_zero_l) {
- zero_s = tmp_zero_s;
- zero_l = tmp_zero_l;
- tmp_zero_l = 0;
- }
- }
- }
-
- if (tmp_zero_l && zero_l < tmp_zero_l) {
- zero_s = tmp_zero_s;
- zero_l = tmp_zero_l;
- }
-
- if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
- ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
- ((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
- is_ipv4 = 1;
-
- /* Format whole words. */
- for (p = 0; p < words; p++) {
- if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) {
- /* Time to skip some zeros */
- if (p == zero_s)
- *cp++ = ':';
- if (p == words - 1)
- *cp++ = ':';
- s++;
- s++;
- continue;
- }
+ if (inet_ntop(AF_INET6, src, buf, size) == NULL)
+ return (NULL);
- if (is_ipv4 && p > 5 ) {
- *cp++ = (p == 6) ? ':' : '.';
- cp += SPRINTF((cp, "%u", *s++));
- /* we can potentially drop the last octet */
- if (p != 7 || bits > 120) {
- *cp++ = '.';
- cp += SPRINTF((cp, "%u", *s++));
- }
- } else {
- if (cp != outbuf)
- *cp++ = ':';
- cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
- s += 2;
- }
- }
+ ret = snprintf(dst, size, "%s/%d", buf, bits);
+ if (ret < 0 || ret >= size) {
+ errno = EMSGSIZE;
+ return (NULL);
}
- /* Format CIDR /width. */
- sprintf(cp, "/%u", bits);
- if (strlen(outbuf) + 1 > size)
- goto emsgsize;
- strcpy(dst, outbuf);
return (dst);
-
-emsgsize:
- errno = EMSGSIZE;
- return (NULL);
}
/*
@@ -271,5 +171,3 @@ emsgsize:
*/
#undef inet_net_ntop
__weak_reference(__inet_net_ntop, inet_net_ntop);
-
-/*! \file */
diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c
index d566a0e1d3c3..14c88eb72014 100644
--- a/lib/libc/inet/inet_net_pton.c
+++ b/lib/libc/inet/inet_net_pton.c
@@ -1,20 +1,23 @@
-/*-
- * SPDX-License-Identifier: ISC
+/* $OpenBSD: inet_net_pton.c,v 1.14 2022/12/27 17:10:06 jmc Exp $ */
+
+/*
+ * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org>
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
*
- * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1996, 1998, 1999, 2001, 2003 Internet Software Consortium.
+ * SPDX-License-Identifier: ISC
*
- * Permission to use, copy, modify, and/or distribute this software for any
+ * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#include "port_before.h"
@@ -22,7 +25,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
-#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <assert.h>
@@ -34,13 +36,37 @@
#include "port_after.h"
-#ifdef SPRINTF_CHAR
-# define SPRINTF(x) strlen(sprintf/**/x)
-#else
-# define SPRINTF(x) ((size_t)sprintf x)
-#endif
+static int inet_net_pton_ipv4(const char *, u_char *, size_t);
+static int inet_net_pton_ipv6(const char *, u_char *, size_t);
-/*%
+/*
+ * static int
+ * inet_net_pton(af, src, dst, size)
+ * convert network number from presentation to network format.
+ * accepts hex octets, hex strings, decimal octets, and /CIDR.
+ * "size" is in bytes and describes "dst".
+ * return:
+ * number of bits, either imputed classfully or specified with /CIDR,
+ * or -1 if some failure occurred (check errno). ENOENT means it was
+ * not a valid network specification.
+ * author:
+ * Paul Vixie (ISC), June 1996
+ */
+int
+inet_net_pton(int af, const char *src, void *dst, size_t size)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_net_pton_ipv4(src, dst, size));
+ case AF_INET6:
+ return (inet_net_pton_ipv6(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+}
+
+/*
* static int
* inet_net_pton_ipv4(src, dst, size)
* convert IPv4 network number from presentation to network format.
@@ -57,22 +83,24 @@
* Paul Vixie (ISC), June 1996
*/
static int
-inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
- static const char xdigits[] = "0123456789abcdef";
- static const char digits[] = "0123456789";
- int n, ch, tmp = 0, dirty, bits;
+inet_net_pton_ipv4(const char *src, u_char *dst, size_t size)
+{
+ static const char
+ xdigits[] = "0123456789abcdef",
+ digits[] = "0123456789";
+ int n, ch, tmp, dirty, bits;
const u_char *odst = dst;
- ch = *src++;
+ ch = (unsigned char)*src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
- && isascii((unsigned char)(src[1]))
- && isxdigit((unsigned char)(src[1]))) {
+ && isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) {
/* Hexadecimal: Eat nybble string. */
- if (size <= 0U)
+ if (size == 0)
goto emsgsize;
- dirty = 0;
- src++; /*%< skip x or X. */
- while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
+ tmp = 0, dirty = 0;
+ src++; /* skip x or X. */
+ while ((ch = (unsigned char)*src++) != '\0' &&
+ isascii(ch) && isxdigit(ch)) {
if (isupper(ch))
ch = tolower(ch);
n = strchr(xdigits, ch) - xdigits;
@@ -82,14 +110,14 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
else
tmp = (tmp << 4) | n;
if (++dirty == 2) {
- if (size-- <= 0U)
+ if (size-- == 0)
goto emsgsize;
*dst++ = (u_char) tmp;
dirty = 0;
}
}
- if (dirty) { /*%< Odd trailing nybble? */
- if (size-- <= 0U)
+ if (dirty) { /* Odd trailing nybble? */
+ if (size-- == 0)
goto emsgsize;
*dst++ = (u_char) (tmp << 4);
}
@@ -104,16 +132,16 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
tmp += n;
if (tmp > 255)
goto enoent;
- } while ((ch = *src++) != '\0' &&
+ } while ((ch = (unsigned char)*src++) != '\0' &&
isascii(ch) && isdigit(ch));
- if (size-- <= 0U)
+ if (size-- == 0)
goto emsgsize;
*dst++ = (u_char) tmp;
if (ch == '\0' || ch == '/')
break;
if (ch != '.')
goto enoent;
- ch = *src++;
+ ch = (unsigned char)*src++;
if (!isascii(ch) || !isdigit(ch))
goto enoent;
}
@@ -121,10 +149,10 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
goto enoent;
bits = -1;
- if (ch == '/' && isascii((unsigned char)(src[0])) &&
- isdigit((unsigned char)(src[0])) && dst > odst) {
+ if (ch == '/' && isascii((unsigned char)src[0]) &&
+ isdigit((unsigned char)src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */
- ch = *src++; /*%< Skip over the /. */
+ ch = (unsigned char)*src++; /* Skip over the /. */
bits = 0;
do {
n = strchr(digits, ch) - digits;
@@ -132,8 +160,9 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
bits *= 10;
bits += n;
if (bits > 32)
- goto enoent;
- } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
+ goto emsgsize;
+ } while ((ch = (unsigned char)*src++) != '\0' &&
+ isascii(ch) && isdigit(ch));
if (ch != '\0')
goto enoent;
}
@@ -147,29 +176,23 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
goto enoent;
/* If no CIDR spec was given, infer width from net class. */
if (bits == -1) {
- if (*odst >= 240) /*%< Class E */
+ if (*odst >= 240) /* Class E */
bits = 32;
- else if (*odst >= 224) /*%< Class D */
- bits = 8;
- else if (*odst >= 192) /*%< Class C */
+ else if (*odst >= 224) /* Class D */
+ bits = 4;
+ else if (*odst >= 192) /* Class C */
bits = 24;
- else if (*odst >= 128) /*%< Class B */
+ else if (*odst >= 128) /* Class B */
bits = 16;
- else /*%< Class A */
+ else /* Class A */
bits = 8;
/* If imputed mask is narrower than specified octets, widen. */
if (bits < ((dst - odst) * 8))
bits = (dst - odst) * 8;
- /*
- * If there are no additional bits specified for a class D
- * address adjust bits to 4.
- */
- if (bits == 8 && *odst == 224)
- bits = 4;
}
/* Extend network to cover the actual mask. */
while (bits > ((dst - odst) * 8)) {
- if (size-- <= 0U)
+ if (size-- == 0)
goto emsgsize;
*dst++ = '\0';
}
@@ -184,222 +207,48 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
return (-1);
}
-static int
-getbits(const char *src, int *bitsp) {
- static const char digits[] = "0123456789";
- int n;
- int val;
- char ch;
-
- val = 0;
- n = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- pch = strchr(digits, ch);
- if (pch != NULL) {
- if (n++ != 0 && val == 0) /*%< no leading zeros */
- return (0);
- val *= 10;
- val += (pch - digits);
- if (val > 128) /*%< range */
- return (0);
- continue;
- }
- return (0);
- }
- if (n == 0)
- return (0);
- *bitsp = val;
- return (1);
-}
static int
-getv4(const char *src, u_char *dst, int *bitsp) {
- static const char digits[] = "0123456789";
- u_char *odst = dst;
- int n;
- u_int val;
- char ch;
-
- val = 0;
- n = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
+inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
+{
+ struct in6_addr in6;
+ int ret;
+ int bits;
+ size_t bytes;
+ char buf[INET6_ADDRSTRLEN + sizeof("/128")];
+ char *sep;
+ const char *errstr;
- pch = strchr(digits, ch);
- if (pch != NULL) {
- if (n++ != 0 && val == 0) /*%< no leading zeros */
- return (0);
- val *= 10;
- val += (pch - digits);
- if (val > 255) /*%< range */
- return (0);
- continue;
- }
- if (ch == '.' || ch == '/') {
- if (dst - odst > 3) /*%< too many octets? */
- return (0);
- *dst++ = val;
- if (ch == '/')
- return (getbits(src, bitsp));
- val = 0;
- n = 0;
- continue;
- }
- return (0);
+ if (strlcpy(buf, src, sizeof buf) >= sizeof buf) {
+ errno = EMSGSIZE;
+ return (-1);
}
- if (n == 0)
- return (0);
- if (dst - odst > 3) /*%< too many octets? */
- return (0);
- *dst++ = val;
- return (1);
-}
-static int
-inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
- static const char xdigits_l[] = "0123456789abcdef",
- xdigits_u[] = "0123456789ABCDEF";
- u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
- const char *xdigits, *curtok;
- int ch, saw_xdigit;
- u_int val;
- int digits;
- int bits;
- size_t bytes;
- int words;
- int ipv4;
+ sep = strchr(buf, '/');
+ if (sep != NULL)
+ *sep++ = '\0';
- memset((tp = tmp), '\0', NS_IN6ADDRSZ);
- endp = tp + NS_IN6ADDRSZ;
- colonp = NULL;
- /* Leading :: requires some special handling. */
- if (*src == ':')
- if (*++src != ':')
- goto enoent;
- curtok = src;
- saw_xdigit = 0;
- val = 0;
- digits = 0;
- bits = -1;
- ipv4 = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
+ ret = inet_pton(AF_INET6, buf, &in6);
+ if (ret != 1)
+ return (-1);
- if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
- pch = strchr((xdigits = xdigits_u), ch);
- if (pch != NULL) {
- val <<= 4;
- val |= (pch - xdigits);
- if (++digits > 4)
- goto enoent;
- saw_xdigit = 1;
- continue;
- }
- if (ch == ':') {
- curtok = src;
- if (!saw_xdigit) {
- if (colonp)
- goto enoent;
- colonp = tp;
- continue;
- } else if (*src == '\0')
- goto enoent;
- if (tp + NS_INT16SZ > endp)
- return (0);
- *tp++ = (u_char) (val >> 8) & 0xff;
- *tp++ = (u_char) val & 0xff;
- saw_xdigit = 0;
- digits = 0;
- val = 0;
- continue;
- }
- if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
- getv4(curtok, tp, &bits) > 0) {
- tp += NS_INADDRSZ;
- saw_xdigit = 0;
- ipv4 = 1;
- break; /*%< '\\0' was seen by inet_pton4(). */
- }
- if (ch == '/' && getbits(src, &bits) > 0)
- break;
- goto enoent;
- }
- if (saw_xdigit) {
- if (tp + NS_INT16SZ > endp)
- goto enoent;
- *tp++ = (u_char) (val >> 8) & 0xff;
- *tp++ = (u_char) val & 0xff;
- }
- if (bits == -1)
+ if (sep == NULL)
bits = 128;
-
- words = (bits + 15) / 16;
- if (words < 2)
- words = 2;
- if (ipv4)
- words = 8;
- endp = tmp + 2 * words;
-
- if (colonp != NULL) {
- /*
- * Since some memmove()'s erroneously fail to handle
- * overlapping regions, we'll do the shift by hand.
- */
- const int n = tp - colonp;
- int i;
-
- if (tp == endp)
- goto enoent;
- for (i = 1; i <= n; i++) {
- endp[- i] = colonp[n - i];
- colonp[n - i] = 0;
+ else {
+ bits = strtonum(sep, 0, 128, &errstr);
+ if (errstr) {
+ errno = EINVAL;
+ return (-1);
}
- tp = endp;
}
- if (tp != endp)
- goto enoent;
bytes = (bits + 7) / 8;
- if (bytes > size)
- goto emsgsize;
- memcpy(dst, tmp, bytes);
- return (bits);
-
- enoent:
- errno = ENOENT;
- return (-1);
-
- emsgsize:
- errno = EMSGSIZE;
- return (-1);
-}
-
-/*%
- * int
- * inet_net_pton(af, src, dst, size)
- * convert network number from presentation to network format.
- * accepts hex octets, hex strings, decimal octets, and /CIDR.
- * "size" is in bytes and describes "dst".
- * return:
- * number of bits, either imputed classfully or specified with /CIDR,
- * or -1 if some failure occurred (check errno). ENOENT means it was
- * not a valid network specification.
- * author:
- * Paul Vixie (ISC), June 1996
- */
-int
-inet_net_pton(int af, const char *src, void *dst, size_t size) {
- switch (af) {
- case AF_INET:
- return (inet_net_pton_ipv4(src, dst, size));
- case AF_INET6:
- return (inet_net_pton_ipv6(src, dst, size));
- default:
- errno = EAFNOSUPPORT;
+ if (bytes > size) {
+ errno = EMSGSIZE;
return (-1);
}
+ memcpy(dst, &in6.s6_addr, bytes);
+ return (bits);
}
/*
@@ -408,5 +257,3 @@ inet_net_pton(int af, const char *src, void *dst, size_t size) {
*/
#undef inet_net_pton
__weak_reference(__inet_net_pton, inet_net_pton);
-
-/*! \file */
diff --git a/lib/libc/tests/net/Makefile b/lib/libc/tests/net/Makefile
index 24cff61e8d24..ec0668633508 100644
--- a/lib/libc/tests/net/Makefile
+++ b/lib/libc/tests/net/Makefile
@@ -4,8 +4,10 @@ ATF_TESTS_C+= ether_test
ATF_TESTS_C+= eui64_aton_test
ATF_TESTS_C+= eui64_ntoa_test
ATF_TESTS_CXX+= link_addr_test
+ATF_TESTS_CXX+= inet_net_test
CXXSTD.link_addr_test= c++20
+CXXSTD.inet_net_test= c++20
CFLAGS+= -I${.CURDIR}
diff --git a/lib/libc/tests/net/inet_net_test.cc b/lib/libc/tests/net/inet_net_test.cc
new file mode 100644
index 000000000000..60b60b152eca
--- /dev/null
+++ b/lib/libc/tests/net/inet_net_test.cc
@@ -0,0 +1,333 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2025 Lexi Winter <ivy@FreeBSD.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Tests for inet_net_pton() and inet_net_ntop().
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ranges>
+#include <string>
+#include <vector>
+
+#include <atf-c++.hpp>
+
+using namespace std::literals;
+
+/*
+ * inet_net_ntop() and inet_net_pton() for IPv4.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(inet_net_inet4)
+ATF_TEST_CASE_BODY(inet_net_inet4)
+{
+ /*
+ * Define a list of addresses we want to check. Each address is passed
+ * to inet_net_pton() to convert it to an in_addr, then we convert the
+ * in_addr back to a string and compare it with the expected value. We
+ * want to test over-long prefixes here (such as 10.0.0.1/8), so we also
+ * specify what the result is expected to be.
+ */
+
+ struct test_addr {
+ std::string input;
+ int bits;
+ std::string output;
+ };
+
+ auto test_addrs = std::vector<test_addr>{
+ // Simple prefixes that fall on octet boundaries.
+ { "10.0.0.0/8", 8, "10/8" },
+ { "10.1.0.0/16", 16, "10.1/16" },
+ { "10.1.2.0/24", 24, "10.1.2/24" },
+ { "10.1.2.3/32", 32, "10.1.2.3/32" },
+
+ // Simple prefixes with the short-form address.
+ { "10/8", 8, "10/8" },
+ { "10.1/16", 16, "10.1/16" },
+ { "10.1.2/24", 24, "10.1.2/24" },
+
+ // A prefix that doesn't fall on an octet boundary.
+ { "10.1.64/18", 18, "10.1.64/18" },
+
+ // An overlong prefix with bits that aren't part of the prefix.
+ { "10.0.0.1/8", 8, "10/8" },
+ };
+
+ for (auto const &addr: test_addrs) {
+ /*
+ * Convert the input string to an in_addr + bits, and make
+ * sure the result produces the number of bits we expected.
+ */
+
+ auto in = in_addr{};
+ auto bits = inet_net_pton(AF_INET, addr.input.c_str(),
+ &in, sizeof(in));
+ ATF_REQUIRE(bits != -1);
+ ATF_REQUIRE_EQ(bits, addr.bits);
+
+ /*
+ * Convert the in_addr back to a string
+ */
+
+ /*
+ * XXX: Should there be a constant for the size of the result
+ * buffer? For now, use ADDRSTRLEN + 3 ("/32") + 1 (NUL).
+ *
+ * Fill the buffer with 'Z', so we can check the result was
+ * properly terminated.
+ */
+ auto strbuf = std::vector<char>(INET_ADDRSTRLEN + 3 + 1, 'Z');
+ auto ret = inet_net_ntop(AF_INET, &in, bits,
+ strbuf.data(), strbuf.size());
+ ATF_REQUIRE(ret != NULL);
+ ATF_REQUIRE_EQ(ret, strbuf.data());
+
+ /* Make sure the result was NUL-terminated and find the NUL */
+ ATF_REQUIRE(strbuf.size() >= 1);
+ auto end = std::ranges::find(strbuf, '\0');
+ ATF_REQUIRE(end != strbuf.end());
+
+ /*
+ * Check the result matches what we expect. Use a temporary
+ * string here instead of std::ranges::equal because this
+ * means ATF can print the mismatch.
+ */
+ auto str = std::string(std::ranges::begin(strbuf), end);
+ ATF_REQUIRE_EQ(str, addr.output);
+ }
+}
+
+/*
+ * inet_net_ntop() and inet_net_pton() for IPv6.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(inet_net_inet6)
+ATF_TEST_CASE_BODY(inet_net_inet6)
+{
+ /*
+ * Define a list of addresses we want to check. Each address is
+ * passed to inet_net_pton() to convert it to an in6_addr, then we
+ * convert the in6_addr back to a string and compare it with the
+ * expected value. We want to test over-long prefixes here (such
+ * as 2001:db8::1/32), so we also specify what the result is
+ * expected to be.
+ */
+
+ struct test_addr {
+ std::string input;
+ int bits;
+ std::string output;
+ };
+
+ auto test_addrs = std::vector<test_addr>{
+ // A prefix with a trailing ::
+ { "2001:db8::/32", 32, "2001:db8::/32" },
+
+ // A prefix with a leading ::. Note that the output is
+ // different from the input because inet_ntop() renders
+ // this prefix with an IPv4 suffix for legacy reasons.
+ { "::ffff:0:0/96", 96, "::ffff:0.0.0.0/96" },
+
+ // The same prefix but with the IPv4 legacy form as input.
+ { "::ffff:0.0.0.0/96", 96, "::ffff:0.0.0.0/96" },
+
+ // A prefix with an infix ::.
+ { "2001:db8::1/128", 128, "2001:db8::1/128" },
+
+ // A prefix with bits set which are outside the prefix;
+ // these should be silently ignored.
+ { "2001:db8:1:1:1:1:1:1/32", 32, "2001:db8::/32" },
+
+ // As above but with infix ::.
+ { "2001:db8::1/32", 32, "2001:db8::/32" },
+
+ // A prefix with only ::, commonly used to represent the
+ // entire address space.
+ { "::/0", 0, "::/0" },
+
+ // A single address with no ::.
+ { "2001:db8:1:1:1:1:1:1/128", 128, "2001:db8:1:1:1:1:1:1/128" },
+
+ // A prefix with no ::.
+ { "2001:db8:1:1:0:0:0:0/64", 64, "2001:db8:1:1::/64" },
+
+ // A prefix which isn't on a 16-bit boundary.
+ { "2001:db8:c000::/56", 56, "2001:db8:c000::/56" },
+
+ // A prefix which isn't on a nibble boundary.
+ { "2001:db8:c100::/57", 57, "2001:db8:c100::/57" },
+
+ // An address without a prefix length, which should be treated
+ // as a /128.
+ { "2001:db8::", 128, "2001:db8::/128" },
+ { "2001:db8::1", 128, "2001:db8::1/128" },
+
+ // Test vectors provided in PR bin/289198.
+ { "fe80::1/64", 64, "fe80::/64" },
+ { "fe80::f000:74ff:fe54:bed2/64",
+ 64, "fe80::/64" },
+ { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64",
+ 64, "ffff:ffff:ffff:ffff::/64" },
+ { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128,
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" },
+ };
+
+ for (auto const &addr: test_addrs) {
+ /*
+ * Convert the input string to an in6_addr + bits, and make
+ * sure the result produces the number of bits we expected.
+ */
+
+ auto in6 = in6_addr{};
+ errno = 0;
+ auto bits = inet_net_pton(AF_INET6, addr.input.c_str(),
+ &in6, sizeof(in6));
+ ATF_REQUIRE(bits != -1);
+ ATF_REQUIRE_EQ(bits, addr.bits);
+
+ /*
+ * Convert the in6_addr back to a string
+ */
+
+ /*
+ * XXX: Should there be a constant for the size of the result
+ * buffer? For now, use ADDRSTRLEN + 4 ("/128") + 1 (NUL).
+ *
+ * Fill the buffer with 'Z', so we can check the result was
+ * properly terminated.
+ */
+ auto strbuf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1, 'Z');
+ auto ret = inet_net_ntop(AF_INET6, &in6, bits,
+ strbuf.data(), strbuf.size());
+ ATF_REQUIRE(ret != NULL);
+ ATF_REQUIRE_EQ(ret, strbuf.data());
+
+ /* Make sure the result was NUL-terminated and find the NUL */
+ ATF_REQUIRE(strbuf.size() >= 1);
+ auto end = std::ranges::find(strbuf, '\0');
+ ATF_REQUIRE(end != strbuf.end());
+
+ /*
+ * Check the result matches what we expect. Use a temporary
+ * string here instead of std::ranges::equal because this
+ * means ATF can print the mismatch.
+ */
+ auto str = std::string(std::ranges::begin(strbuf), end);
+ ATF_REQUIRE_EQ(str, addr.output);
+ }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(inet_net_pton_invalid)
+ATF_TEST_CASE_BODY(inet_net_pton_invalid)
+{
+ auto ret = int{};
+ auto addr4 = in_addr{};
+ auto str4 = "10.0.0.0"s;
+ auto addr6 = in6_addr{};
+ auto str6 = "2001:db8::"s;
+
+ /* Passing an address which is too short should be an error */
+ ret = inet_net_pton(AF_INET6, str6.c_str(), &addr6, sizeof(addr6) - 1);
+ ATF_REQUIRE_EQ(ret, -1);
+
+ ret = inet_net_pton(AF_INET, str4.c_str(), &addr4, sizeof(addr4) - 1);
+ ATF_REQUIRE_EQ(ret, -1);
+
+ /* Test some generally invalid addresses. */
+ auto invalid4 = std::vector<std::string>{
+ // Prefix length too big
+ "10.0.0.0/33",
+ // Prefix length is negative
+ "10.0.0.0/-1",
+ // Prefix length is not a number
+ "10.0.0.0/foo",
+ // Input is not a network prefix
+ "this is not an IP address",
+ };
+
+ for (auto const &addr: invalid4) {
+ auto ret = inet_net_pton(AF_INET, addr.c_str(), &addr4,
+ sizeof(addr4));
+ ATF_REQUIRE_EQ(ret, -1);
+ }
+
+ auto invalid6 = std::vector<std::string>{
+ // Prefix length too big
+ "2001:db8::/129",
+ // Prefix length is negative
+ "2001:db8::/-1",
+ // Prefix length is not a number
+ "2001:db8::/foo",
+ // Input is not a network prefix
+ "this is not an IP address",
+ };
+
+ for (auto const &addr: invalid6) {
+ auto ret = inet_net_pton(AF_INET6, addr.c_str(), &addr6,
+ sizeof(addr6));
+ ATF_REQUIRE_EQ(ret, -1);
+ }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(inet_net_ntop_invalid)
+ATF_TEST_CASE_BODY(inet_net_ntop_invalid)
+{
+ auto addr4 = in_addr{};
+ auto addr6 = in6_addr{};
+ auto strbuf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1);
+
+ /*
+ * Passing a buffer which is too small should not overrun the buffer.
+ * Test this by initialising the buffer to 'Z', and only providing
+ * part of it to the function.
+ */
+
+ std::ranges::fill(strbuf, 'Z');
+ auto ret = inet_net_ntop(AF_INET6, &addr6, 128, strbuf.data(), 1);
+ ATF_REQUIRE_EQ(ret, nullptr);
+ ATF_REQUIRE_EQ(strbuf[1], 'Z');
+
+ std::ranges::fill(strbuf, 'Z');
+ ret = inet_net_ntop(AF_INET, &addr4, 32, strbuf.data(), 1);
+ ATF_REQUIRE_EQ(ret, nullptr);
+ ATF_REQUIRE_EQ(strbuf[1], 'Z');
+
+ /* Check that invalid prefix lengths return an error */
+
+ ret = inet_net_ntop(AF_INET6, &addr6, 129, strbuf.data(), strbuf.size());
+ ATF_REQUIRE_EQ(ret, nullptr);
+ ret = inet_net_ntop(AF_INET6, &addr6, -1, strbuf.data(), strbuf.size());
+ ATF_REQUIRE_EQ(ret, nullptr);
+
+ ret = inet_net_ntop(AF_INET, &addr4, 33, strbuf.data(), strbuf.size());
+ ATF_REQUIRE_EQ(ret, nullptr);
+ ret = inet_net_ntop(AF_INET, &addr4, -1, strbuf.data(), strbuf.size());
+ ATF_REQUIRE_EQ(ret, nullptr);
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, inet_net_inet4);
+ ATF_ADD_TEST_CASE(tcs, inet_net_inet6);
+ ATF_ADD_TEST_CASE(tcs, inet_net_pton_invalid);
+ ATF_ADD_TEST_CASE(tcs, inet_net_ntop_invalid);
+}
diff --git a/lib/libsys/kqueue.2 b/lib/libsys/kqueue.2
index 96c9b0222a37..a8ebabf02cf7 100644
--- a/lib/libsys/kqueue.2
+++ b/lib/libsys/kqueue.2
@@ -97,10 +97,37 @@ system call also creates a new kernel event queue, and additionally takes
a
.Fa flags
argument, which is a bitwise-inclusive OR of the following flags:
-.Bl -tag -width "KQUEUE_CLOEXEC"
+.Bl -tag -width "KQUEUE_CPONFORK"
.It Dv KQUEUE_CLOEXEC
The returned file descriptor is automatically closed on
.Xr execve 2
+.It Dv KQUEUE_CPONFORK
+When this flag is set, the created kqueue is copied into
+the child process on
+.Xr fork 2
+calls.
+The kqueue descriptor index of the new kqueue will be inherited by the child,
+that is, the numeric value of the descriptor will remain the same.
+.Pp
+Copying is deep, that is, each registered event in the original kqueue is
+copied (and not shared) into the new kqueue.
+This is contrary to how other descriptor types are handled upon
+.Xr fork 2 ,
+where the copied file descriptor references the same file object
+as the source descriptor (shallow copy).
+.Pp
+By default, in other words, when the flag is not set, kqueues from
+the parent are not copied on fork to the child process.
+The corresponding file descriptor indeces are unused in the child.
+.Pp
+Registered events that reference file descriptors which are not
+duplicated on fork, are not copied into the new kqueue.
+For instance, if the event references a file descriptor opened with the
+.Dv O_CLOEXEC
+flag set, it is not copied.
+Similarly, if event references a kqueue opened without the
+.Dv KQUEUE_CPONFORK
+flag, the event is not copied.
.El
.Pp
The
diff --git a/lib/libutil/mntopts.c b/lib/libutil/mntopts.c
index 07d3dd6d98a3..4a064a086fd5 100644
--- a/lib/libutil/mntopts.c
+++ b/lib/libutil/mntopts.c
@@ -145,6 +145,18 @@ checkpath_allow_file(const char *path, char *resolved)
return (0);
}
+static char *
+prependdevtopath(const char *path, char *buf, u_long buflen)
+{
+ u_long len;
+
+ if ((len = strlen(_PATH_DEV) + strlen(path) + 1) > buflen)
+ return NULL;
+ strncpy(buf, _PATH_DEV, len);
+ strncat(buf, path, len - sizeof(_PATH_DEV));
+ return (buf);
+}
+
/*
* Get the mount point information for name. Name may be mount point name
* or device name (with or without /dev/ preprended).
@@ -153,19 +165,27 @@ struct statfs *
getmntpoint(const char *name)
{
struct stat devstat, mntdevstat;
- char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
- char *ddevname;
+ char *devname;
struct statfs *mntbuf, *statfsp;
- int i, mntsize, isdev;
- u_long len;
+ int i, len, isdev, mntsize, mntfromnamesize;
+ char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
+ u_long devlen;
- if (stat(name, &devstat) != 0)
+ devlen = sizeof(device);
+ /*
+ * Note that stat(NULL, &statbuf) returns -1 (EBADF) which will
+ * cause us to return NULL if prependdevtopath() returns NULL.
+ */
+ if (stat(name, &devstat) != 0 &&
+ (name[0] != '/' &&
+ stat(prependdevtopath(name, device, devlen), &devstat) != 0))
return (NULL);
if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
isdev = 1;
else
isdev = 0;
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+ mntfromnamesize = sizeof(statfsp->f_mntfromname);
for (i = 0; i < mntsize; i++) {
statfsp = &mntbuf[i];
if (isdev == 0) {
@@ -173,19 +193,20 @@ getmntpoint(const char *name)
continue;
return (statfsp);
}
- ddevname = statfsp->f_mntfromname;
- if (*ddevname != '/') {
- if ((len = strlen(_PATH_DEV) + strlen(ddevname) + 1) >
- sizeof(statfsp->f_mntfromname) ||
- len > sizeof(device))
+ devname = statfsp->f_mntfromname;
+ if (*devname == '/') {
+ if (stat(devname, &mntdevstat) != 0)
+ continue;
+ } else {
+ devname = prependdevtopath(devname, device, devlen);
+ if (devname == NULL ||
+ (len = strlen(devname)) > mntfromnamesize)
+ continue;
+ if (stat(devname, &mntdevstat) != 0)
continue;
- strncpy(device, _PATH_DEV, len);
- strncat(device, ddevname, len);
- if (stat(device, &mntdevstat) == 0)
- strncpy(statfsp->f_mntfromname, device, len);
+ strncpy(statfsp->f_mntfromname, devname, len);
}
- if (stat(ddevname, &mntdevstat) == 0 &&
- S_ISCHR(mntdevstat.st_mode) &&
+ if (S_ISCHR(mntdevstat.st_mode) &&
mntdevstat.st_rdev == devstat.st_rdev)
return (statfsp);
}
diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf
index b7cce777c4f6..ada9094360f6 100644
--- a/libexec/rc/rc.conf
+++ b/libexec/rc/rc.conf
@@ -24,7 +24,7 @@
: ${_localbase:="$(/sbin/sysctl -n user.localbase 2> /dev/null)"}
: ${_localbase:="/usr/local"}
-# rc_debug can't be set here without interferring with rc.subr's setting it
+# rc_debug can't be set here without interfering with rc.subr's setting it
# when the kenv variable rc.debug is set.
#rc_debug="NO" # Set to YES to enable debugging output from rc.d
rc_info="NO" # Enables display of informational messages at boot.
@@ -707,6 +707,7 @@ osrelease_enable="YES" # Update /var/run/os-release on boot (or NO).
osrelease_file="/var/run/os-release" # File to update for os-release.
osrelease_perms="444" # Default permission for os-release file.
dmesg_enable="YES" # Save dmesg(8) to /var/run/dmesg.boot
+dmesg_umask="022" # Default umask for /var/run/dmesg.boot file.
watchdogd_enable="NO" # Start the software watchdog daemon
watchdogd_flags="" # Flags to watchdogd (if enabled)
watchdogd_timeout="" # watchdogd timeout, overrides -t in watchdogd_flags
diff --git a/libexec/rc/rc.d/dmesg b/libexec/rc/rc.d/dmesg
index 51e35d5d4e80..736449f3b159 100755
--- a/libexec/rc/rc.d/dmesg
+++ b/libexec/rc/rc.d/dmesg
@@ -19,7 +19,7 @@ stop_cmd=":"
do_dmesg()
{
rm -f ${dmesg_file}
- ( umask 022 ; /sbin/dmesg $rc_flags > ${dmesg_file} )
+ ( umask "${dmesg_umask}" ; /sbin/dmesg $rc_flags > ${dmesg_file} )
}
load_rc_config $name
diff --git a/libexec/rc/rc.d/hostapd b/libexec/rc/rc.d/hostapd
index 264cb4ef476b..15b20c95c488 100755
--- a/libexec/rc/rc.d/hostapd
+++ b/libexec/rc/rc.d/hostapd
@@ -11,15 +11,6 @@
name="hostapd"
desc="Authenticator for IEEE 802.11 networks"
command=${hostapd_program}
-start_postcmd="hostapd_poststart"
-
-hostapd_poststart() {
- if [ -n "$ifn" ]; then
- ifconfig ${ifn} down
- sleep 2
- ifconfig ${ifn} up
- fi
-}
ifn="$2"
if [ -z "$ifn" ]; then
diff --git a/release/Makefile b/release/Makefile
index 13532097d56c..a777ded3c429 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -430,6 +430,8 @@ pkg-stage: dvd
mkdir -p ${.OBJDIR}/dvd/packages/repos/
cp ${.CURDIR}/scripts/FreeBSD_install_cdrom.conf \
${.OBJDIR}/dvd/packages/repos/
+ echo "./packages/repos type=dir uname=root gname=wheel mode=0755" >> dvd/METALOG
+ echo "./packages/repos/FreeBSD_install_cdrom.conf type=file uname=root gname=wheel mode=0644" >> dvd/METALOG
.endif
touch ${.TARGET}
diff --git a/release/Makefile.oracle b/release/Makefile.oracle
index 3573f29b96c1..6d792cc9fd30 100644
--- a/release/Makefile.oracle
+++ b/release/Makefile.oracle
@@ -24,21 +24,28 @@
# Syncing to all sites should take 2-3 hours after this final step.
ORACLE_BASENAME= ${OSRELEASE}-${BUILDDATE}${GITREV:C/^(.+)/-\1/}
-ORACLE_PORTS_LIST= ftp/curl emulators/qemu@tools
CLEANFILES+= cw-oracle-portinstall
cw-oracle-portinstall: .PHONY
-.if !exists(/usr/local/bin/curl) || !exists(/usr/local/bin/qemu-img)
-. if !exists(${PORTSDIR}/Makefile)
-. if !exists(/usr/local/sbin/pkg-static)
+.if (!exists(/usr/local/bin/curl) || !exists(/usr/local/bin/qemu-img)) && !exists(${PORTSDIR}/Makefile)
+. if !exists(/usr/local/sbin/pkg-static)
env ASSUME_ALWAYS_YES=yes pkg bootstrap -yf
-. endif
- env ASSUME_ALWAYS_YES=yes pkg install -y ${ORACLE_PORTS_LIST}
+. endif
+.endif
+.if !exists(/usr/local/bin/curl)
+. if !exists(${PORTSDIR}/Makefile)
+ env ASSUME_ALWAYS_YES=yes pkg install -y ftp/curl
. else
env UNAME_r=${UNAME_r} make -C \
${PORTSDIR}/ftp/curl \
BATCH=1 WRKDIRPREFIX=/tmp/ports DISTDIR=/tmp/distfiles \
all install clean
+. endif
+.endif
+.if !exists(/usr/local/bin/qemu-img)
+. if !exists(${PORTSDIR}/Makefile)
+ env ASSUME_ALWAYS_YES=yes pkg install -y emulators/qemu@tools
+. else
env UNAME_r=${UNAME_r} FLAVOR=tools make -C \
${PORTSDIR}/emulators/qemu \
BATCH=1 WRKDIRPREFIX=/tmp/ports DISTDIR=/tmp/distfiles \
diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr
index 842a808c623e..99e1936296e1 100644
--- a/release/tools/vmimage.subr
+++ b/release/tools/vmimage.subr
@@ -213,16 +213,6 @@ vm_extra_install_packages() {
install -y -r ${PKG_REPO_NAME} $pkg
done
metalog_add_data ./var/db/pkg/local.sqlite
-
- # Add some database files which are created by pkg triggers;
- # at some point in the future the tools which create these
- # files should probably learn how to record them in METALOG
- # (which would simplify no-root installworld as well).
- metalog_add_data ./etc/login.conf.db
- metalog_add_data ./etc/passwd
- metalog_add_data ./etc/pwd.db
- metalog_add_data ./etc/spwd.db 600
- metalog_add_data ./var/db/services.db
else
if [ -n "${WITHOUT_QEMU}" ]; then
return 0
@@ -290,28 +280,42 @@ buildfs() {
cat ${DESTDIR}/METALOG.pkg >> ${DESTDIR}/METALOG
fi
- # Check for any directories in the staging tree which weren't
- # recorded in METALOG, and record them now. This is a quick hack
- # to avoid creating unusable VM images and should go away once
- # the bugs which produce such unlogged directories are gone.
- grep type=dir ${DESTDIR}/METALOG |
- cut -f 1 -d ' ' |
- sort -u > ${DESTDIR}/METALOG.dirs
- ( cd ${DESTDIR} && find . -type d ) |
- sort |
- comm -23 - ${DESTDIR}/METALOG.dirs > ${DESTDIR}/METALOG.missingdirs
- if [ -s ${DESTDIR}/METALOG.missingdirs ]; then
- echo "WARNING: Directories exist but were not in METALOG"
- cat ${DESTDIR}/METALOG.missingdirs
+ if [ -n "${NO_ROOT}" ]; then
+ # Check for any directories in the staging tree which weren't
+ # recorded in METALOG, and record them now. This is a quick hack
+ # to avoid creating unusable VM images and should go away once
+ # the bugs which produce such unlogged directories are gone.
+ grep type=dir ${DESTDIR}/METALOG |
+ cut -f 1 -d ' ' |
+ sort -u > ${DESTDIR}/METALOG.dirs
+ ( cd ${DESTDIR} && find . -type d ) |
+ sort |
+ comm -23 - ${DESTDIR}/METALOG.dirs > ${DESTDIR}/METALOG.missingdirs
+ if [ -s ${DESTDIR}/METALOG.missingdirs ]; then
+ echo "WARNING: Directories exist but were not in METALOG"
+ cat ${DESTDIR}/METALOG.missingdirs
+ fi
+ while read DIR; do
+ metalog_add_data ${DIR}
+ done < ${DESTDIR}/METALOG.missingdirs
+
+ if [ -z "${NOPKGBASE}" ]; then
+ # Add some database files which are created by pkg triggers;
+ # at some point in the future the tools which create these
+ # files should probably learn how to record them in METALOG
+ # (which would simplify no-root installworld as well).
+ metalog_add_data ./etc/login.conf.db
+ metalog_add_data ./etc/passwd
+ metalog_add_data ./etc/pwd.db
+ metalog_add_data ./etc/spwd.db 600
+ metalog_add_data ./var/db/services.db
+ fi
+
+ # Sort METALOG file; makefs produces directories with 000 permissions
+ # if their contents are seen before the directories themselves.
+ env -i LC_COLLATE=C sort -u ${DESTDIR}/METALOG > ${DESTDIR}/METALOG.sorted
+ mv ${DESTDIR}/METALOG.sorted ${DESTDIR}/METALOG
fi
- while read DIR; do
- metalog_add_data ${DIR}
- done < ${DESTDIR}/METALOG.missingdirs
-
- # Sort METALOG file; makefs produces directories with 000 permissions
- # if their contents are seen before the directories themselves.
- env -i LC_COLLATE=C sort -u ${DESTDIR}/METALOG > ${DESTDIR}/METALOG.sorted
- mv ${DESTDIR}/METALOG.sorted ${DESTDIR}/METALOG
case "${VMFS}" in
ufs)
diff --git a/sbin/devd/snd.conf b/sbin/devd/snd.conf
index cf9cd9e94191..a45f427f6c79 100644
--- a/sbin/devd/snd.conf
+++ b/sbin/devd/snd.conf
@@ -5,6 +5,9 @@ notify 0 {
match "type" "IN";
match "cdev" "dsp[0-9]+";
+ # Other audio servers or device switching commands can be used here
+ # instead of virtual_oss(8).
+ #
# FIXME: We are hardcoding /dev/vdsp.ctl here, simply because it is a
# common virtual_oss control device name. Until we find a proper way to
# define control devices here, /dev/vdsp.ctl can be changed to the
@@ -18,6 +21,6 @@ notify 0 {
match "type" "OUT";
match "cdev" "dsp[0-9]+";
- # FIXME: See comment above.
+ # See comment above.
action "/usr/sbin/virtual_oss_cmd /dev/vdsp.ctl -P /dev/$cdev";
};
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 1a4f7e1f061a..2de696ce6a43 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -1189,10 +1189,11 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
gotone = len = 0;
xo_open_instance("status");
LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
+ if (cp->lg_provider == NULL)
+ continue;
+
cstate = status_one_consumer(cp, "state");
csyncr = status_one_consumer(cp, "synchronized");
- if (cstate == NULL && csyncr == NULL)
- continue;
if (!gotone || script) {
if (!gotone) {
xo_emit("{:name/%*s} {:status/%*s} ",
@@ -1206,14 +1207,17 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
xo_open_instance("components");
if (cstate != NULL && csyncr != NULL) {
- xo_emit("{P:/%*s}{:compontent} ({:state}, {:synchronized})\n",
+ xo_emit("{P:/%*s}{:component} ({:state}, {:synchronized})\n",
len, "", cp->lg_provider->lg_name, cstate, csyncr);
} else if (cstate != NULL) {
- xo_emit("{P:/%*s}{:compontent} ({:state})\n",
+ xo_emit("{P:/%*s}{:component} ({:state})\n",
len, "", cp->lg_provider->lg_name, cstate);
- } else {
- xo_emit("{P:/%*s}{:compontent} ({:synchronized})\n",
+ } else if (csyncr != NULL) {
+ xo_emit("{P:/%*s}{:component} ({:synchronized})\n",
len, "", cp->lg_provider->lg_name, csyncr);
+ } else {
+ xo_emit("{P:/%*s}{:component}\n",
+ len, "", cp->lg_provider->lg_name);
}
xo_close_instance("components");
gotone = 1;
@@ -1224,7 +1228,7 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
xo_emit("{:name/%*s} {:status/%*s} ", name_len, name, status_len, status);
xo_open_list("components");
xo_open_instance("components");
- xo_emit("{P:/%*s}{d:compontent}\n", len, "", "N/A");
+ xo_emit("{P:/%*s}{d:component}\n", len, "", "N/A");
xo_close_instance("components");
}
xo_close_list("components");
@@ -1258,11 +1262,11 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
}
gotone = len = 0;
LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
- cstate = status_one_consumer(cp, "state");
- csyncr = status_one_consumer(cp, "synchronized");
- if (cstate == NULL && csyncr == NULL)
+ if (cp->lg_provider == NULL)
continue;
+ cstate = status_one_consumer(cp, "state");
+ csyncr = status_one_consumer(cp, "synchronized");
if (!gotone || script) {
if (!gotone) {
xo_emit("{:name/%*s} {:status/%*s} ",
@@ -1276,14 +1280,17 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
xo_open_instance("component");
if (cstate != NULL && csyncr != NULL) {
- xo_emit("{P:/%*s}{:compontent} ({:state}, {:synchronized})\n",
+ xo_emit("{P:/%*s}{:component} ({:state}, {:synchronized})\n",
len, "", cp->lg_provider->lg_name, cstate, csyncr);
} else if (cstate != NULL) {
- xo_emit("{P:/%*s}{:compontent} ({:state})\n",
+ xo_emit("{P:/%*s}{:component} ({:state})\n",
len, "", cp->lg_provider->lg_name, cstate);
- } else {
- xo_emit("{P:/%*s}{:compontent} ({:synchronized})\n",
+ } else if (csyncr != NULL) {
+ xo_emit("{P:/%*s}{:component} ({:synchronized})\n",
len, "", cp->lg_provider->lg_name, csyncr);
+ } else {
+ xo_emit("{P:/%*s}{:component}\n",
+ len, "", cp->lg_provider->lg_name);
}
xo_close_instance("component");
gotone = 1;
@@ -1294,7 +1301,7 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
xo_emit("{:name/%*s} {:status/%*s} ", name_len, name, status_len, status);
xo_open_list("components");
xo_open_instance("components");
- xo_emit("{P:/%*s}{d:compontent}\n", len, "", "N/A");
+ xo_emit("{P:/%*s}{d:component}\n", len, "", "N/A");
xo_close_instance("components");
}
xo_close_list("components");
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 6e076722c786..e94e832a3f94 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -69,6 +69,12 @@ MAN= aac.4 \
audit.4 \
auditpipe.4 \
aue.4 \
+ ${_aw_gpio.4} \
+ ${_aw_mmc.4} \
+ ${_aw_rtc.4} \
+ ${_aw_sid.4} \
+ ${_aw_spi.4} \
+ ${_aw_syscon.4} \
axe.4 \
axge.4 \
axp.4 \
@@ -962,6 +968,12 @@ _vmx.4= vmx.4
.if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "aarch64" || \
${MACHINE_CPUARCH} == "riscv"
+_aw_gpio.4= aw_gpio.4
+_aw_mmc.4= aw_mmc.4
+_aw_rtc.4= aw_rtc.4
+_aw_sid.4= aw_sid.4
+_aw_spi.4= aw_spi.4
+_aw_syscon.4= aw_syscon.4
_cgem.4= cgem.4
MLINKS+=cgem.4 if_cgem.4
.endif
diff --git a/share/man/man4/man4.arm/aw_gpio.4 b/share/man/man4/aw_gpio.4
index ef9fc1fe2733..5cbc7562d9bd 100644
--- a/share/man/man4/man4.arm/aw_gpio.4
+++ b/share/man/man4/aw_gpio.4
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd October 8, 2024
-.Dt AW_GPIO 4 arm
+.Dt AW_GPIO 4
.Os
.Sh NAME
.Nm aw_gpio
diff --git a/share/man/man4/man4.arm/aw_mmc.4 b/share/man/man4/aw_mmc.4
index e3f961fa5067..072835cce7c0 100644
--- a/share/man/man4/man4.arm/aw_mmc.4
+++ b/share/man/man4/aw_mmc.4
@@ -22,8 +22,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Dec 25, 2017
-.Dt AW_MMC 4 arm
+.Dd October 20, 2025
+.Dt AW_MMC 4
.Os
.Sh NAME
.Nm aw_mmc
@@ -48,6 +48,8 @@ allwinner,sun5i-a13-mmc
allwinner,sun7i-a20-mmc
.It
allwinner,sun50i-a64-mmc
+.It
+allwinner,sun20i-d1-mmc
.El
.Sh SYSCTL VARIABLES
The following read-only variables are available via
diff --git a/share/man/man4/man4.arm/aw_rtc.4 b/share/man/man4/aw_rtc.4
index 87212d85116c..1296cd41da68 100644
--- a/share/man/man4/man4.arm/aw_rtc.4
+++ b/share/man/man4/aw_rtc.4
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd December 10, 2024
-.Dt AW_RTC 4 arm
+.Dt AW_RTC 4
.Os
.Sh NAME
.Nm aw_rtc
diff --git a/share/man/man4/man4.arm/aw_sid.4 b/share/man/man4/aw_sid.4
index 8b3691259f22..5cd2f3d5e072 100644
--- a/share/man/man4/man4.arm/aw_sid.4
+++ b/share/man/man4/aw_sid.4
@@ -25,7 +25,7 @@
.\" SUCH DAMAGE.
.\"
.Dd October 8, 2024
-.Dt AW_SID 4 arm
+.Dt AW_SID 4
.Os
.Sh NAME
.Nm aw_sid
diff --git a/share/man/man4/man4.arm/aw_spi.4 b/share/man/man4/aw_spi.4
index d0566a45b54b..f8985e1c16bb 100644
--- a/share/man/man4/man4.arm/aw_spi.4
+++ b/share/man/man4/aw_spi.4
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd May 17, 2018
-.Dt AW_SPI 4 arm
+.Dt AW_SPI 4
.Os
.Sh NAME
.Nm aw_spi
diff --git a/share/man/man4/man4.arm/aw_syscon.4 b/share/man/man4/aw_syscon.4
index 97f01196a8a6..e32f329e489a 100644
--- a/share/man/man4/man4.arm/aw_syscon.4
+++ b/share/man/man4/aw_syscon.4
@@ -25,7 +25,7 @@
.\" SUCH DAMAGE.
.\"
.Dd November 11, 2024
-.Dt AW_SYSCON 4 arm
+.Dt AW_SYSCON 4
.Os
.Sh NAME
.Nm aw_syscon
diff --git a/share/man/man4/man4.aarch64/Makefile b/share/man/man4/man4.aarch64/Makefile
index 0e85aab8b770..f35558d69a33 100644
--- a/share/man/man4/man4.aarch64/Makefile
+++ b/share/man/man4/man4.aarch64/Makefile
@@ -14,12 +14,6 @@ MAN= \
# for all architectures, otherwise arm takes care of installing them.
.if !empty(MAN_ARCH) && ${MAN_ARCH} != "all"
MAN+= \
- aw_gpio.4 \
- aw_mmc.4 \
- aw_rtc.4 \
- aw_sid.4 \
- aw_spi.4 \
- aw_syscon.4 \
bcm283x_pwm.4 \
.endif
diff --git a/share/man/man4/man4.arm/Makefile b/share/man/man4/man4.arm/Makefile
index 6b046a1002a2..2be255ad913f 100644
--- a/share/man/man4/man4.arm/Makefile
+++ b/share/man/man4/man4.arm/Makefile
@@ -1,11 +1,5 @@
MAN= \
ar40xx.4 \
- aw_gpio.4 \
- aw_mmc.4 \
- aw_rtc.4 \
- aw_sid.4 \
- aw_spi.4 \
- aw_syscon.4 \
bcm283x_pwm.4 \
devcfg.4 \
imx6_ahci.4 \
diff --git a/share/man/man4/snd_dummy.4 b/share/man/man4/snd_dummy.4
index 2b9d26d318ef..172b8ed70729 100644
--- a/share/man/man4/snd_dummy.4
+++ b/share/man/man4/snd_dummy.4
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 15, 2024
+.Dd October 22, 2025
.Dt SND_DUMMY 4
.Os
.Sh NAME
@@ -47,11 +47,22 @@ physical sound card.
It is intended for testing, so that test programs do not need to rely on
hardware being present in the machine in order to run.
.Pp
-The driver attaches as a regular PCM device, with two channels (one playback
-and one recording), as well as a mixer.
+The driver attaches as a regular
+.Xr sound 4
+device, with two channels (one playback and one recording), as well as a mixer.
.Pp
Playback works by discarding all input, and recording by returning silence
(zeros).
+.Sh FILES
+.Bl -tag -width "/dev/dsp.dummy" -compact
+.It Pa /dev/dsp.dummy
+Alias to the device's
+.Pa /dev/dsp%d
+file created by
+.Xr sound 4 .
+This makes it easy for tests to open the dummy devic when there are more
+devices present in the system.
+.El
.Sh SEE ALSO
.Xr sound 4 ,
.Xr loader.conf 5 ,
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 1bb609336532..bab2c3d84abf 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,5 +1,5 @@
.\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
-.Dd October 1, 2025
+.Dd October 22, 2025
.Dt SRC.CONF 5
.Os
.Sh NAME
@@ -956,12 +956,12 @@ Do not build LLVM's lld linker.
Do not build the LLDB debugger.
.Pp
This is a default setting on
-arm/armv7 and riscv/riscv64.
+riscv/riscv64.
.It Va WITH_LLDB
Build the LLDB debugger.
.Pp
This is a default setting on
-amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc64 and powerpc/powerpc64le.
+amd64/amd64, arm/armv7, arm64/aarch64, i386/i386, powerpc/powerpc64 and powerpc/powerpc64le.
.It Va WITHOUT_LLD_BOOTSTRAP
Do not build the LLD linker during the bootstrap phase of
the build.
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 3bccc92572d6..52ec9be3ae02 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -2207,6 +2207,7 @@ MLINKS+=syscall_helper_register.9 syscall_helper_unregister.9 \
syscall_helper_register.9 SYSCALL_INIT_HELPER_COMPAT_F.9 \
syscall_helper_register.9 SYSCALL_INIT_HELPER_F.9
MLINKS+=sysctl.9 SYSCTL_DECL.9 \
+ sysctl.9 SYSCTL_ADD_BOOL.9 \
sysctl.9 SYSCTL_ADD_CONST_STRING.9 \
sysctl.9 SYSCTL_ADD_INT.9 \
sysctl.9 SYSCTL_ADD_LONG.9 \
@@ -2233,6 +2234,7 @@ MLINKS+=sysctl.9 SYSCTL_DECL.9 \
sysctl.9 SYSCTL_ADD_UMA_CUR.9 \
sysctl.9 SYSCTL_ADD_UMA_MAX.9 \
sysctl.9 SYSCTL_ADD_UQUAD.9 \
+ sysctl.9 SYSCTL_BOOL.9 \
sysctl.9 SYSCTL_CHILDREN.9 \
sysctl.9 SYSCTL_STATIC_CHILDREN.9 \
sysctl.9 SYSCTL_NODE_CHILDREN.9 \
diff --git a/share/man/man9/VOP_OPENCLOSE.9 b/share/man/man9/VOP_OPENCLOSE.9
index 9a4f7069962d..672f9faa92f5 100644
--- a/share/man/man9/VOP_OPENCLOSE.9
+++ b/share/man/man9/VOP_OPENCLOSE.9
@@ -26,7 +26,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd December 2, 2009
+.Dd October 17, 2025
.Dt VOP_OPEN 9
.Os
.Sh NAME
@@ -78,6 +78,17 @@ The access mode is a set of flags, including
.Dv FWRITE ,
.Dv O_NONBLOCK ,
.Dv O_APPEND .
+.Pp
+The thread
+.Fa td
+passed to
+.Fn VOP_CLOSE
+may be
+.Ql NULL
+if the last reference to the open file is released from a kernel context, e.g.,
+the destruction of a socket buffer containing the file reference in a
+.Dv SCM_RIGHTS
+message.
.Sh LOCKS
.Fn VOP_OPEN
expects
diff --git a/share/man/man9/uio.9 b/share/man/man9/uio.9
index e6240c4e51d3..b143eb6e8e62 100644
--- a/share/man/man9/uio.9
+++ b/share/man/man9/uio.9
@@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd March 11, 2017
+.Dd October 22, 2025
.Dt UIO 9
.Os
.Sh NAME
@@ -107,10 +107,14 @@ The I/O vector points into the kernel address space.
Do not copy, already in object.
.El
.It Va uio_rw
-The direction of the desired transfer, either
-.Dv UIO_READ
-or
-.Dv UIO_WRITE .
+The direction of the desired transfer.
+The supported flags are:
+.Bl -tag -width "UIO_WRITE"
+.It Dv UIO_READ
+Transfer data from the buffers into the I/O vectors.
+.It Dv UIO_WRITE
+Transfer data from the I/O vectors into the buffers.
+.El
.It Va uio_td
The pointer to a
.Vt "struct thread"
diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree
index b1614c7eb409..b0502dfc7925 100644
--- a/share/misc/bsd-family-tree
+++ b/share/misc/bsd-family-tree
@@ -479,7 +479,7 @@ FreeBSD 5.2 | | | |
| | | | | DragonFly 6.4.1
| | | | | DragonFly 6.4.2
| FreeBSD | | | |
- | 14.3 | | | |
+ | 14.3 | | OpenBSD 7.8 |
| | | | |
FreeBSD 16 -current | NetBSD -current OpenBSD -current DragonFly -current
| | | | |
@@ -925,6 +925,7 @@ OpenBSD 7.7 2025-04-28 [OBD]
DragonFly 6.4.1 2025-04-30 [DFB]
DragonFly 6.4.2 2025-05-09 [DFB]
FreeBSD 14.3 2025-06-10 [FBD]
+OpenBSD 7.8 2025-10-22 [OBD]
Bibliography
------------------------
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index 6035dd031216..3f3e39635c55 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -188,6 +188,7 @@ fjoe [label="Max Khon\nfjoe@FreeBSD.org\n2001/08/06"]
flz [label="Florent Thoumie\nflz@FreeBSD.org\n2006/03/30"]
freqlabs [label="Ryan Moeller\nfreqlabs@FreeBSD.org\n2020/02/10"]
fsu [label="Fedor Uporov\nfsu@FreeBSD.org\n2017/08/28"]
+fuz [label="Robert Clausecker\nfuz@FreeBSD.org\n2025/10/21"]
gabor [label="Gabor Kovesdan\ngabor@FreeBSD.org\n2010/02/02"]
gad [label="Garance A. Drosehn\ngad@FreeBSD.org\n2000/10/27"]
gallatin [label="Andrew Gallatin\ngallatin@FreeBSD.org\n1999/01/15"]
@@ -789,6 +790,7 @@ markj -> bnovkov
markj -> cem
markj -> christos
markj -> dougm
+markj -> fuz
markj -> igoro
markj -> jfree
markj -> lwhsu
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 446f78a2acf3..e10455cd4e82 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -302,7 +302,7 @@ __DEFAULT_NO_OPTIONS+=FDT
__DEFAULT_YES_OPTIONS+=FDT
.endif
-.if ${__T:Marm*} == "" && ${__T:Mriscv64*} == ""
+.if ${__T:Mriscv64*} == ""
__DEFAULT_YES_OPTIONS+=LLDB
.else
__DEFAULT_NO_OPTIONS+=LLDB
diff --git a/sys/amd64/pt/pt.c b/sys/amd64/pt/pt.c
index c7b75767680a..6b2296de049c 100644
--- a/sys/amd64/pt/pt.c
+++ b/sys/amd64/pt/pt.c
@@ -42,15 +42,15 @@
*/
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/hwt.h>
+#include <sys/interrupt.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
-#include <sys/sdt.h>
#include <sys/smp.h>
-#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -94,12 +94,7 @@
MALLOC_DEFINE(M_PT, "pt", "Intel Processor Trace");
-SDT_PROVIDER_DEFINE(pt);
-SDT_PROBE_DEFINE(pt, , , topa__intr);
-
-TASKQUEUE_FAST_DEFINE_THREAD(pt);
-
-static void pt_send_buffer_record(void *arg, int pending __unused);
+static void pt_send_buffer_record(void *arg);
static int pt_topa_intr(struct trapframe *tf);
/*
@@ -122,29 +117,24 @@ struct pt_buffer {
size_t size;
struct mtx lock; /* Lock for fields below. */
vm_offset_t offset;
- uint64_t wrap_count;
- int curpage;
};
struct pt_ctx {
int id;
struct pt_buffer buf; /* ToPA buffer metadata */
- struct task task; /* ToPA buffer notification task */
struct hwt_context *hwt_ctx;
uint8_t *save_area; /* PT XSAVE area */
};
/* PT tracing contexts used for CPU mode. */
static struct pt_ctx *pt_pcpu_ctx;
-enum pt_cpu_state {
- PT_DISABLED = 0,
- PT_STOPPED,
- PT_ACTIVE
-};
+enum pt_cpu_state { PT_INACTIVE = 0, PT_ACTIVE };
static struct pt_cpu {
struct pt_ctx *ctx; /* active PT tracing context */
enum pt_cpu_state state; /* used as part of trace stop protocol */
+ void *swi_cookie; /* Software interrupt handler context */
+ int in_pcint_handler;
} *pt_pcpu;
/*
@@ -199,31 +189,28 @@ static __inline void
pt_update_buffer(struct pt_buffer *buf)
{
uint64_t reg;
- int curpage;
+ uint64_t offset;
/* Update buffer offset. */
reg = rdmsr(MSR_IA32_RTIT_OUTPUT_MASK_PTRS);
- curpage = (reg & PT_TOPA_PAGE_MASK) >> PT_TOPA_PAGE_SHIFT;
- mtx_lock_spin(&buf->lock);
- /* Check if the output wrapped. */
- if (buf->curpage > curpage)
- buf->wrap_count++;
- buf->curpage = curpage;
- buf->offset = reg >> 32;
- mtx_unlock_spin(&buf->lock);
-
- dprintf("%s: wrap_cnt: %lu, curpage: %d, offset: %zu\n", __func__,
- buf->wrap_count, buf->curpage, buf->offset);
+ offset = ((reg & PT_TOPA_PAGE_MASK) >> PT_TOPA_PAGE_SHIFT) * PAGE_SIZE;
+ offset += (reg >> 32);
+
+ atomic_store_rel_64(&buf->offset, offset);
}
static __inline void
pt_fill_buffer_record(int id, struct pt_buffer *buf,
struct hwt_record_entry *rec)
{
+ vm_offset_t offset;
+
+ offset = atomic_load_acq_64(&buf->offset);
+
rec->record_type = HWT_RECORD_BUFFER;
rec->buf_id = id;
- rec->curpage = buf->curpage;
- rec->offset = buf->offset + (buf->wrap_count * buf->size);
+ rec->curpage = offset / PAGE_SIZE;
+ rec->offset = offset & PAGE_MASK;
}
/*
@@ -273,9 +260,9 @@ pt_cpu_start(void *dummy)
MPASS(cpu->ctx != NULL);
dprintf("%s: curcpu %d\n", __func__, curcpu);
+ pt_cpu_set_state(curcpu, PT_ACTIVE);
load_cr4(rcr4() | CR4_XSAVE);
wrmsr(MSR_IA32_RTIT_STATUS, 0);
- pt_cpu_set_state(curcpu, PT_ACTIVE);
pt_cpu_toggle_local(cpu->ctx->save_area, true);
}
@@ -291,16 +278,16 @@ pt_cpu_stop(void *dummy)
struct pt_cpu *cpu;
struct pt_ctx *ctx;
- /* Shutdown may occur before PT gets properly configured. */
- if (pt_cpu_get_state(curcpu) == PT_DISABLED)
- return;
-
cpu = &pt_pcpu[curcpu];
ctx = cpu->ctx;
- MPASS(ctx != NULL);
- dprintf("%s: curcpu %d\n", __func__, curcpu);
- pt_cpu_set_state(curcpu, PT_STOPPED);
+ dprintf("%s: curcpu %d\n", __func__, curcpu);
+ /* Shutdown may occur before PT gets properly configured. */
+ if (ctx == NULL) {
+ dprintf("%s: missing context on cpu %d; bailing\n", __func__,
+ curcpu);
+ return;
+ }
pt_cpu_toggle_local(cpu->ctx->save_area, false);
pt_update_buffer(&ctx->buf);
}
@@ -406,13 +393,11 @@ pt_init_ctx(struct pt_ctx *pt_ctx, struct hwt_vm *vm, int ctx_id)
return (ENOMEM);
dprintf("%s: preparing ToPA buffer\n", __func__);
if (pt_topa_prepare(pt_ctx, vm) != 0) {
- dprintf("%s: failed to prepare ToPA buffer\n", __func__);
free(pt_ctx->save_area, M_PT);
return (ENOMEM);
}
pt_ctx->id = ctx_id;
- TASK_INIT(&pt_ctx->task, 0, pt_send_buffer_record, pt_ctx);
return (0);
}
@@ -426,7 +411,6 @@ pt_deinit_ctx(struct pt_ctx *pt_ctx)
if (pt_ctx->save_area != NULL)
free(pt_ctx->save_area, M_PT);
memset(pt_ctx, 0, sizeof(*pt_ctx));
- pt_ctx->buf.topa_hw = NULL;
}
/*
@@ -519,7 +503,6 @@ pt_backend_configure(struct hwt_context *ctx, int cpu_id, int thread_id)
XSTATE_XCOMP_BV_COMPACT;
pt_ext->rtit_ctl |= RTIT_CTL_TRACEEN;
pt_pcpu[cpu_id].ctx = pt_ctx;
- pt_cpu_set_state(cpu_id, PT_STOPPED);
return (0);
}
@@ -549,12 +532,19 @@ pt_backend_disable(struct hwt_context *ctx, int cpu_id)
if (ctx->mode == HWT_MODE_CPU)
return;
-
KASSERT(curcpu == cpu_id,
("%s: attempting to disable PT on another cpu", __func__));
+
+ cpu = &pt_pcpu[cpu_id];
+
+ dprintf("%s: waiting for cpu %d to exit interrupt handler\n", __func__,
+ cpu_id);
+ pt_cpu_set_state(cpu_id, PT_INACTIVE);
+ while (atomic_cmpset_int(&cpu->in_pcint_handler, 1, 0))
+ ;
+
pt_cpu_stop(NULL);
CPU_CLR(cpu_id, &ctx->cpu_map);
- cpu = &pt_pcpu[cpu_id];
cpu->ctx = NULL;
}
@@ -564,14 +554,14 @@ pt_backend_disable(struct hwt_context *ctx, int cpu_id)
static int
pt_backend_enable_smp(struct hwt_context *ctx)
{
-
dprintf("%s\n", __func__);
+
+ KASSERT(ctx->mode == HWT_MODE_CPU,
+ ("%s: should only be used for CPU mode", __func__));
if (ctx->mode == HWT_MODE_CPU &&
atomic_swap_32(&cpu_mode_ctr, 1) != 0)
return (-1);
- KASSERT(ctx->mode == HWT_MODE_CPU,
- ("%s: should only be used for CPU mode", __func__));
smp_rendezvous_cpus(ctx->cpu_map, NULL, pt_cpu_start, NULL, NULL);
return (0);
@@ -583,6 +573,7 @@ pt_backend_enable_smp(struct hwt_context *ctx)
static int
pt_backend_disable_smp(struct hwt_context *ctx)
{
+ struct pt_cpu *cpu;
dprintf("%s\n", __func__);
if (ctx->mode == HWT_MODE_CPU &&
@@ -593,6 +584,14 @@ pt_backend_disable_smp(struct hwt_context *ctx)
dprintf("%s: empty cpu map\n", __func__);
return (-1);
}
+ CPU_FOREACH_ISSET(cpu_id, &ctx->cpu_map) {
+ cpu = &pt_pcpu[cpu_id];
+ dprintf("%s: waiting for cpu %d to exit interrupt handler\n",
+ __func__, cpu_id);
+ pt_cpu_set_state(cpu_id, PT_INACTIVE);
+ while (atomic_cmpset_int(&cpu->in_pcint_handler, 1, 0))
+ ;
+ }
smp_rendezvous_cpus(ctx->cpu_map, NULL, pt_cpu_stop, NULL, NULL);
return (0);
@@ -611,13 +610,13 @@ pt_backend_init(struct hwt_context *ctx)
int error;
dprintf("%s\n", __func__);
- if (ctx->mode == HWT_MODE_CPU) {
- TAILQ_FOREACH(hwt_cpu, &ctx->cpus, next) {
- error = pt_init_ctx(&pt_pcpu_ctx[hwt_cpu->cpu_id],
- hwt_cpu->vm, hwt_cpu->cpu_id);
- if (error)
- return (error);
- }
+ if (ctx->mode != HWT_MODE_CPU)
+ return (0);
+ TAILQ_FOREACH(hwt_cpu, &ctx->cpus, next) {
+ error = pt_init_ctx(&pt_pcpu_ctx[hwt_cpu->cpu_id], hwt_cpu->vm,
+ hwt_cpu->cpu_id);
+ if (error)
+ return (error);
}
return (0);
@@ -647,20 +646,16 @@ pt_backend_deinit(struct hwt_context *ctx)
pt_deinit_ctx(pt_ctx);
}
} else {
- CPU_FOREACH(cpu_id) {
- if (!CPU_ISSET(cpu_id, &ctx->cpu_map))
+ CPU_FOREACH_ISSET(cpu_id, &ctx->cpu_map) {
+ if (pt_pcpu[cpu_id].ctx == NULL)
continue;
- if (pt_pcpu[cpu_id].ctx != NULL) {
- KASSERT(pt_pcpu[cpu_id].ctx ==
- &pt_pcpu_ctx[cpu_id],
- ("%s: CPU mode tracing with non-cpu mode PT"
- "context active",
- __func__));
- pt_pcpu[cpu_id].ctx = NULL;
- }
- pt_ctx = &pt_pcpu_ctx[cpu_id];
- pt_deinit_ctx(pt_ctx);
- memset(&pt_pcpu[cpu_id], 0, sizeof(struct pt_cpu));
+ KASSERT(pt_pcpu[cpu_id].ctx == &pt_pcpu_ctx[cpu_id],
+ ("%s: CPU mode tracing with non-cpu mode PT"
+ "context active",
+ __func__));
+ pt_deinit_ctx(pt_pcpu[cpu_id].ctx);
+ pt_pcpu[cpu_id].ctx = NULL;
+ atomic_set_int(&pt_pcpu[cpu_id].in_pcint_handler, 0);
}
}
@@ -675,15 +670,15 @@ pt_backend_read(struct hwt_vm *vm, int *curpage, vm_offset_t *curpage_offset,
uint64_t *data)
{
struct pt_buffer *buf;
+ uint64_t offset;
if (vm->ctx->mode == HWT_MODE_THREAD)
buf = &((struct pt_ctx *)vm->thr->private)->buf;
else
buf = &pt_pcpu[vm->cpu->cpu_id].ctx->buf;
- mtx_lock_spin(&buf->lock);
- *curpage = buf->curpage;
- *curpage_offset = buf->offset + (buf->wrap_count * vm->ctx->bufsize);
- mtx_unlock_spin(&buf->lock);
+ offset = atomic_load_acq_64(&buf->offset);
+ *curpage = offset / PAGE_SIZE;
+ *curpage_offset = offset & PAGE_MASK;
return (0);
}
@@ -762,15 +757,13 @@ static struct hwt_backend backend = {
* Used as a taskqueue routine from the ToPA interrupt handler.
*/
static void
-pt_send_buffer_record(void *arg, int pending __unused)
+pt_send_buffer_record(void *arg)
{
+ struct pt_cpu *cpu = (struct pt_cpu *)arg;
struct hwt_record_entry record;
- struct pt_ctx *ctx = (struct pt_ctx *)arg;
- /* Prepare buffer record. */
- mtx_lock_spin(&ctx->buf.lock);
+ struct pt_ctx *ctx = cpu->ctx;
pt_fill_buffer_record(ctx->id, &ctx->buf, &record);
- mtx_unlock_spin(&ctx->buf.lock);
hwt_record_ctx(ctx->hwt_ctx, &record, M_ZERO | M_NOWAIT);
}
static void
@@ -795,36 +788,40 @@ static int
pt_topa_intr(struct trapframe *tf)
{
struct pt_buffer *buf;
+ struct pt_cpu *cpu;
struct pt_ctx *ctx;
uint64_t reg;
- SDT_PROBE0(pt, , , topa__intr);
-
- if (pt_cpu_get_state(curcpu) != PT_ACTIVE) {
- return (0);
- }
+ cpu = &pt_pcpu[curcpu];
reg = rdmsr(MSR_IA_GLOBAL_STATUS);
if ((reg & GLOBAL_STATUS_FLAG_TRACETOPAPMI) == 0) {
- /* ACK spurious or leftover interrupt. */
pt_topa_status_clear();
+ return (0);
+ }
+
+ if (pt_cpu_get_state(curcpu) != PT_ACTIVE) {
return (1);
}
+ atomic_set_int(&cpu->in_pcint_handler, 1);
- ctx = pt_pcpu[curcpu].ctx;
+ ctx = cpu->ctx;
+ KASSERT(ctx != NULL,
+ ("%s: cpu %d: ToPA PMI interrupt without an active context",
+ __func__, curcpu));
buf = &ctx->buf;
KASSERT(buf->topa_hw != NULL,
- ("%s: ToPA PMI interrupt with invalid buffer", __func__));
-
+ ("%s: cpu %d: ToPA PMI interrupt with invalid buffer", __func__,
+ curcpu));
pt_cpu_toggle_local(ctx->save_area, false);
pt_update_buffer(buf);
pt_topa_status_clear();
- taskqueue_enqueue_flags(taskqueue_pt, &ctx->task,
- TASKQUEUE_FAIL_IF_PENDING);
if (pt_cpu_get_state(curcpu) == PT_ACTIVE) {
+ swi_sched(cpu->swi_cookie, SWI_FROMNMI);
pt_cpu_toggle_local(ctx->save_area, true);
lapic_reenable_pcint();
}
+ atomic_set_int(&cpu->in_pcint_handler, 0);
return (1);
}
@@ -839,7 +836,7 @@ static int
pt_init(void)
{
u_int cp[4];
- int error;
+ int error, i;
dprintf("pt: Enumerating part 1\n");
cpuid_count(CPUID_PT_LEAF, 0, cp);
@@ -869,20 +866,38 @@ pt_init(void)
pt_pcpu_ctx = mallocarray(mp_ncpus, sizeof(struct pt_ctx), M_PT,
M_ZERO | M_WAITOK);
+ for (i = 0; i < mp_ncpus; i++) {
+ error = swi_add(&clk_intr_event, "pt", pt_send_buffer_record,
+ &pt_pcpu[i], SWI_CLOCK, INTR_MPSAFE,
+ &pt_pcpu[i].swi_cookie);
+ if (error != 0) {
+ dprintf(
+ "%s: failed to add interrupt handler for cpu: %d\n",
+ __func__, error);
+ goto err;
+ }
+ }
+
nmi_register_handler(pt_topa_intr);
- if (!lapic_enable_pcint()) {
- nmi_remove_handler(pt_topa_intr);
- hwt_backend_unregister(&backend);
- free(pt_pcpu, M_PT);
- free(pt_pcpu_ctx, M_PT);
- pt_pcpu = NULL;
- pt_pcpu_ctx = NULL;
+ if (lapic_enable_pcint()) {
+ initialized = true;
+ return (0);
+ } else
printf("pt: failed to setup interrupt line\n");
- return (error);
+err:
+ nmi_remove_handler(pt_topa_intr);
+ hwt_backend_unregister(&backend);
+
+ for (i = 0; i < mp_ncpus; i++) {
+ if (pt_pcpu[i].swi_cookie != 0)
+ swi_remove(pt_pcpu[i].swi_cookie);
}
- initialized = true;
+ free(pt_pcpu, M_PT);
+ free(pt_pcpu_ctx, M_PT);
+ pt_pcpu = NULL;
+ pt_pcpu_ctx = NULL;
- return (0);
+ return (error);
}
/*
@@ -941,14 +956,24 @@ pt_supported(void)
static void
pt_deinit(void)
{
+ int i;
+ struct pt_cpu *cpu;
+
if (!initialized)
return;
nmi_remove_handler(pt_topa_intr);
lapic_disable_pcint();
hwt_backend_unregister(&backend);
+
+ for (i = 0; i < mp_ncpus; i++) {
+ cpu = &pt_pcpu[i];
+ swi_remove(cpu->swi_cookie);
+ }
+
free(pt_pcpu, M_PT);
free(pt_pcpu_ctx, M_PT);
pt_pcpu = NULL;
+ pt_pcpu_ctx = NULL;
initialized = false;
}
diff --git a/sys/amd64/sgx/sgx_linux.c b/sys/amd64/sgx/sgx_linux.c
index 6ecef9207a38..d389edc1b2b0 100644
--- a/sys/amd64/sgx/sgx_linux.c
+++ b/sys/amd64/sgx/sgx_linux.c
@@ -92,16 +92,7 @@ out:
return (error);
}
-static struct linux_ioctl_handler sgx_linux_handler = {
- sgx_linux_ioctl,
- SGX_LINUX_IOCTL_MIN,
- SGX_LINUX_IOCTL_MAX,
-};
-
-SYSINIT(sgx_linux_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &sgx_linux_handler);
-SYSUNINIT(sgx_linux_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &sgx_linux_handler);
+LINUX_IOCTL_SET(sgx, SGX_LINUX_IOCTL_MIN, SGX_LINUX_IOCTL_MAX);
static int
sgx_linux_modevent(module_t mod, int type, void *data)
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index f7c59847140b..473887240b9b 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -870,7 +870,7 @@ vm_assign_pptdev(struct vm *vm, int bus, int slot, int func)
int
vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval)
{
-
+ /* Negative values represent VM control structure fields. */
if (reg >= VM_REG_LAST)
return (EINVAL);
@@ -882,6 +882,7 @@ vm_set_register(struct vcpu *vcpu, int reg, uint64_t val)
{
int error;
+ /* Negative values represent VM control structure fields. */
if (reg >= VM_REG_LAST)
return (EINVAL);
diff --git a/sys/amd64/vmm/vmm_dev_machdep.c b/sys/amd64/vmm/vmm_dev_machdep.c
index dfebc9dcadbf..b84be809ea24 100644
--- a/sys/amd64/vmm/vmm_dev_machdep.c
+++ b/sys/amd64/vmm/vmm_dev_machdep.c
@@ -124,12 +124,16 @@ const struct vmmdev_ioctl vmmdev_machdep_ioctls[] = {
VMMDEV_IOCTL(VM_SET_KERNEMU_DEV, VMMDEV_IOCTL_LOCK_ONE_VCPU),
VMMDEV_IOCTL(VM_BIND_PPTDEV,
- VMMDEV_IOCTL_XLOCK_MEMSEGS | VMMDEV_IOCTL_LOCK_ALL_VCPUS),
+ VMMDEV_IOCTL_XLOCK_MEMSEGS | VMMDEV_IOCTL_LOCK_ALL_VCPUS |
+ VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
VMMDEV_IOCTL(VM_UNBIND_PPTDEV,
- VMMDEV_IOCTL_XLOCK_MEMSEGS | VMMDEV_IOCTL_LOCK_ALL_VCPUS),
+ VMMDEV_IOCTL_XLOCK_MEMSEGS | VMMDEV_IOCTL_LOCK_ALL_VCPUS |
+ VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
- VMMDEV_IOCTL(VM_MAP_PPTDEV_MMIO, VMMDEV_IOCTL_LOCK_ALL_VCPUS),
- VMMDEV_IOCTL(VM_UNMAP_PPTDEV_MMIO, VMMDEV_IOCTL_LOCK_ALL_VCPUS),
+ VMMDEV_IOCTL(VM_MAP_PPTDEV_MMIO, VMMDEV_IOCTL_LOCK_ALL_VCPUS |
+ VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
+ VMMDEV_IOCTL(VM_UNMAP_PPTDEV_MMIO, VMMDEV_IOCTL_LOCK_ALL_VCPUS |
+ VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
#ifdef BHYVE_SNAPSHOT
#ifdef COMPAT_FREEBSD13
VMMDEV_IOCTL(VM_SNAPSHOT_REQ_13, VMMDEV_IOCTL_LOCK_ALL_VCPUS),
@@ -147,9 +151,9 @@ const struct vmmdev_ioctl vmmdev_machdep_ioctls[] = {
VMMDEV_IOCTL(VM_LAPIC_LOCAL_IRQ, VMMDEV_IOCTL_MAYBE_ALLOC_VCPU),
- VMMDEV_IOCTL(VM_PPTDEV_MSI, 0),
- VMMDEV_IOCTL(VM_PPTDEV_MSIX, 0),
- VMMDEV_IOCTL(VM_PPTDEV_DISABLE_MSIX, 0),
+ VMMDEV_IOCTL(VM_PPTDEV_MSI, VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
+ VMMDEV_IOCTL(VM_PPTDEV_MSIX, VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
+ VMMDEV_IOCTL(VM_PPTDEV_DISABLE_MSIX, VMMDEV_IOCTL_PRIV_CHECK_DRIVER),
VMMDEV_IOCTL(VM_LAPIC_MSI, 0),
VMMDEV_IOCTL(VM_IOAPIC_ASSERT_IRQ, 0),
VMMDEV_IOCTL(VM_IOAPIC_DEASSERT_IRQ, 0),
@@ -172,40 +176,13 @@ int
vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
int fflag, struct thread *td)
{
- struct vm_seg_desc *vmsegdesc;
- struct vm_run *vmrun;
-#ifdef COMPAT_FREEBSD13
- struct vm_run_13 *vmrun_13;
-#endif
- struct vm_exception *vmexc;
- struct vm_lapic_irq *vmirq;
- struct vm_lapic_msi *vmmsi;
- struct vm_ioapic_irq *ioapic_irq;
- struct vm_isa_irq *isa_irq;
- struct vm_isa_irq_trigger *isa_irq_trigger;
- struct vm_pptdev *pptdev;
- struct vm_pptdev_mmio *pptmmio;
- struct vm_pptdev_msi *pptmsi;
- struct vm_pptdev_msix *pptmsix;
- struct vm_x2apic *x2apic;
- struct vm_gpa_pte *gpapte;
- struct vm_gla2gpa *gg;
- struct vm_intinfo *vmii;
- struct vm_rtc_time *rtctime;
- struct vm_rtc_data *rtcdata;
- struct vm_readwrite_kernemu_device *kernemu;
-#ifdef BHYVE_SNAPSHOT
- struct vm_snapshot_meta *snapshot_meta;
-#ifdef COMPAT_FREEBSD13
- struct vm_snapshot_meta_13 *snapshot_13;
-#endif
-#endif
int error;
error = 0;
switch (cmd) {
case VM_RUN: {
struct vm_exit *vme;
+ struct vm_run *vmrun;
vmrun = (struct vm_run *)data;
vme = vm_exitinfo(vcpu);
@@ -243,6 +220,7 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
case VM_RUN_13: {
struct vm_exit *vme;
struct vm_exit_13 *vme_13;
+ struct vm_run_13 *vmrun_13;
vmrun_13 = (struct vm_run_13 *)data;
vme_13 = &vmrun_13->vm_exit;
@@ -281,85 +259,123 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
break;
}
#endif
- case VM_PPTDEV_MSI:
+ case VM_PPTDEV_MSI: {
+ struct vm_pptdev_msi *pptmsi;
+
pptmsi = (struct vm_pptdev_msi *)data;
- error = ppt_setup_msi(vm,
- pptmsi->bus, pptmsi->slot, pptmsi->func,
- pptmsi->addr, pptmsi->msg,
- pptmsi->numvec);
+ error = ppt_setup_msi(vm, pptmsi->bus, pptmsi->slot,
+ pptmsi->func, pptmsi->addr, pptmsi->msg, pptmsi->numvec);
break;
- case VM_PPTDEV_MSIX:
+ }
+ case VM_PPTDEV_MSIX: {
+ struct vm_pptdev_msix *pptmsix;
+
pptmsix = (struct vm_pptdev_msix *)data;
- error = ppt_setup_msix(vm,
- pptmsix->bus, pptmsix->slot,
- pptmsix->func, pptmsix->idx,
- pptmsix->addr, pptmsix->msg,
- pptmsix->vector_control);
+ error = ppt_setup_msix(vm, pptmsix->bus, pptmsix->slot,
+ pptmsix->func, pptmsix->idx, pptmsix->addr, pptmsix->msg,
+ pptmsix->vector_control);
break;
- case VM_PPTDEV_DISABLE_MSIX:
+ }
+ case VM_PPTDEV_DISABLE_MSIX: {
+ struct vm_pptdev *pptdev;
+
pptdev = (struct vm_pptdev *)data;
error = ppt_disable_msix(vm, pptdev->bus, pptdev->slot,
- pptdev->func);
+ pptdev->func);
break;
- case VM_MAP_PPTDEV_MMIO:
+ }
+ case VM_MAP_PPTDEV_MMIO: {
+ struct vm_pptdev_mmio *pptmmio;
+
pptmmio = (struct vm_pptdev_mmio *)data;
error = ppt_map_mmio(vm, pptmmio->bus, pptmmio->slot,
- pptmmio->func, pptmmio->gpa, pptmmio->len,
- pptmmio->hpa);
+ pptmmio->func, pptmmio->gpa, pptmmio->len, pptmmio->hpa);
break;
- case VM_UNMAP_PPTDEV_MMIO:
+ }
+ case VM_UNMAP_PPTDEV_MMIO: {
+ struct vm_pptdev_mmio *pptmmio;
+
pptmmio = (struct vm_pptdev_mmio *)data;
error = ppt_unmap_mmio(vm, pptmmio->bus, pptmmio->slot,
- pptmmio->func, pptmmio->gpa, pptmmio->len);
+ pptmmio->func, pptmmio->gpa, pptmmio->len);
break;
- case VM_BIND_PPTDEV:
+ }
+ case VM_BIND_PPTDEV: {
+ struct vm_pptdev *pptdev;
+
pptdev = (struct vm_pptdev *)data;
error = vm_assign_pptdev(vm, pptdev->bus, pptdev->slot,
- pptdev->func);
+ pptdev->func);
break;
- case VM_UNBIND_PPTDEV:
+ }
+ case VM_UNBIND_PPTDEV: {
+ struct vm_pptdev *pptdev;
+
pptdev = (struct vm_pptdev *)data;
error = vm_unassign_pptdev(vm, pptdev->bus, pptdev->slot,
- pptdev->func);
+ pptdev->func);
break;
- case VM_INJECT_EXCEPTION:
+ }
+ case VM_INJECT_EXCEPTION: {
+ struct vm_exception *vmexc;
+
vmexc = (struct vm_exception *)data;
error = vm_inject_exception(vcpu,
vmexc->vector, vmexc->error_code_valid, vmexc->error_code,
vmexc->restart_instruction);
break;
+ }
case VM_INJECT_NMI:
error = vm_inject_nmi(vcpu);
break;
- case VM_LAPIC_IRQ:
+ case VM_LAPIC_IRQ: {
+ struct vm_lapic_irq *vmirq;
+
vmirq = (struct vm_lapic_irq *)data;
error = lapic_intr_edge(vcpu, vmirq->vector);
break;
- case VM_LAPIC_LOCAL_IRQ:
+ }
+ case VM_LAPIC_LOCAL_IRQ: {
+ struct vm_lapic_irq *vmirq;
+
vmirq = (struct vm_lapic_irq *)data;
error = lapic_set_local_intr(vm, vcpu, vmirq->vector);
break;
- case VM_LAPIC_MSI:
+ }
+ case VM_LAPIC_MSI: {
+ struct vm_lapic_msi *vmmsi;
+
vmmsi = (struct vm_lapic_msi *)data;
error = lapic_intr_msi(vm, vmmsi->addr, vmmsi->msg);
break;
- case VM_IOAPIC_ASSERT_IRQ:
+ }
+ case VM_IOAPIC_ASSERT_IRQ: {
+ struct vm_ioapic_irq *ioapic_irq;
+
ioapic_irq = (struct vm_ioapic_irq *)data;
error = vioapic_assert_irq(vm, ioapic_irq->irq);
break;
- case VM_IOAPIC_DEASSERT_IRQ:
+ }
+ case VM_IOAPIC_DEASSERT_IRQ: {
+ struct vm_ioapic_irq *ioapic_irq;
+
ioapic_irq = (struct vm_ioapic_irq *)data;
error = vioapic_deassert_irq(vm, ioapic_irq->irq);
break;
- case VM_IOAPIC_PULSE_IRQ:
+ }
+ case VM_IOAPIC_PULSE_IRQ: {
+ struct vm_ioapic_irq *ioapic_irq;
+
ioapic_irq = (struct vm_ioapic_irq *)data;
error = vioapic_pulse_irq(vm, ioapic_irq->irq);
break;
+ }
case VM_IOAPIC_PINCOUNT:
*(int *)data = vioapic_pincount(vm);
break;
case VM_SET_KERNEMU_DEV:
case VM_GET_KERNEMU_DEV: {
+ struct vm_readwrite_kernemu_device *kernemu;
mem_region_write_t mwrite;
mem_region_read_t mread;
int size;
@@ -396,60 +412,86 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
error = mread(vcpu, kernemu->gpa,
&kernemu->value, size, &arg);
break;
- }
- case VM_ISA_ASSERT_IRQ:
+ }
+ case VM_ISA_ASSERT_IRQ: {
+ struct vm_isa_irq *isa_irq;
+
isa_irq = (struct vm_isa_irq *)data;
error = vatpic_assert_irq(vm, isa_irq->atpic_irq);
if (error == 0 && isa_irq->ioapic_irq != -1)
error = vioapic_assert_irq(vm, isa_irq->ioapic_irq);
break;
- case VM_ISA_DEASSERT_IRQ:
+ }
+ case VM_ISA_DEASSERT_IRQ: {
+ struct vm_isa_irq *isa_irq;
+
isa_irq = (struct vm_isa_irq *)data;
error = vatpic_deassert_irq(vm, isa_irq->atpic_irq);
if (error == 0 && isa_irq->ioapic_irq != -1)
error = vioapic_deassert_irq(vm, isa_irq->ioapic_irq);
break;
- case VM_ISA_PULSE_IRQ:
+ }
+ case VM_ISA_PULSE_IRQ: {
+ struct vm_isa_irq *isa_irq;
+
isa_irq = (struct vm_isa_irq *)data;
error = vatpic_pulse_irq(vm, isa_irq->atpic_irq);
if (error == 0 && isa_irq->ioapic_irq != -1)
error = vioapic_pulse_irq(vm, isa_irq->ioapic_irq);
break;
- case VM_ISA_SET_IRQ_TRIGGER:
+ }
+ case VM_ISA_SET_IRQ_TRIGGER: {
+ struct vm_isa_irq_trigger *isa_irq_trigger;
+
isa_irq_trigger = (struct vm_isa_irq_trigger *)data;
error = vatpic_set_irq_trigger(vm,
isa_irq_trigger->atpic_irq, isa_irq_trigger->trigger);
break;
- case VM_SET_SEGMENT_DESCRIPTOR:
+ }
+ case VM_SET_SEGMENT_DESCRIPTOR: {
+ struct vm_seg_desc *vmsegdesc;
+
vmsegdesc = (struct vm_seg_desc *)data;
- error = vm_set_seg_desc(vcpu,
- vmsegdesc->regnum,
- &vmsegdesc->desc);
+ error = vm_set_seg_desc(vcpu, vmsegdesc->regnum,
+ &vmsegdesc->desc);
break;
- case VM_GET_SEGMENT_DESCRIPTOR:
+ }
+ case VM_GET_SEGMENT_DESCRIPTOR: {
+ struct vm_seg_desc *vmsegdesc;
+
vmsegdesc = (struct vm_seg_desc *)data;
- error = vm_get_seg_desc(vcpu,
- vmsegdesc->regnum,
- &vmsegdesc->desc);
+ error = vm_get_seg_desc(vcpu, vmsegdesc->regnum,
+ &vmsegdesc->desc);
break;
- case VM_SET_X2APIC_STATE:
+ }
+ case VM_SET_X2APIC_STATE: {
+ struct vm_x2apic *x2apic;
+
x2apic = (struct vm_x2apic *)data;
error = vm_set_x2apic_state(vcpu, x2apic->state);
break;
- case VM_GET_X2APIC_STATE:
+ }
+ case VM_GET_X2APIC_STATE: {
+ struct vm_x2apic *x2apic;
+
x2apic = (struct vm_x2apic *)data;
error = vm_get_x2apic_state(vcpu, &x2apic->state);
break;
- case VM_GET_GPA_PMAP:
+ }
+ case VM_GET_GPA_PMAP: {
+ struct vm_gpa_pte *gpapte;
+
gpapte = (struct vm_gpa_pte *)data;
- pmap_get_mapping(vmspace_pmap(vm_vmspace(vm)),
- gpapte->gpa, gpapte->pte, &gpapte->ptenum);
- error = 0;
+ pmap_get_mapping(vmspace_pmap(vm_vmspace(vm)), gpapte->gpa,
+ gpapte->pte, &gpapte->ptenum);
break;
+ }
case VM_GET_HPET_CAPABILITIES:
error = vhpet_getcap((struct vm_hpet_cap *)data);
break;
case VM_GLA2GPA: {
+ struct vm_gla2gpa *gg;
+
CTASSERT(PROT_READ == VM_PROT_READ);
CTASSERT(PROT_WRITE == VM_PROT_WRITE);
CTASSERT(PROT_EXEC == VM_PROT_EXECUTE);
@@ -460,50 +502,76 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
("%s: vm_gla2gpa unknown error %d", __func__, error));
break;
}
- case VM_GLA2GPA_NOFAULT:
+ case VM_GLA2GPA_NOFAULT: {
+ struct vm_gla2gpa *gg;
+
gg = (struct vm_gla2gpa *)data;
error = vm_gla2gpa_nofault(vcpu, &gg->paging, gg->gla,
gg->prot, &gg->gpa, &gg->fault);
KASSERT(error == 0 || error == EFAULT,
("%s: vm_gla2gpa unknown error %d", __func__, error));
break;
- case VM_SET_INTINFO:
+ }
+ case VM_SET_INTINFO: {
+ struct vm_intinfo *vmii;
+
vmii = (struct vm_intinfo *)data;
error = vm_exit_intinfo(vcpu, vmii->info1);
break;
- case VM_GET_INTINFO:
+ }
+ case VM_GET_INTINFO: {
+ struct vm_intinfo *vmii;
+
vmii = (struct vm_intinfo *)data;
error = vm_get_intinfo(vcpu, &vmii->info1, &vmii->info2);
break;
- case VM_RTC_WRITE:
+ }
+ case VM_RTC_WRITE: {
+ struct vm_rtc_data *rtcdata;
+
rtcdata = (struct vm_rtc_data *)data;
error = vrtc_nvram_write(vm, rtcdata->offset,
rtcdata->value);
break;
- case VM_RTC_READ:
+ }
+ case VM_RTC_READ: {
+ struct vm_rtc_data *rtcdata;
+
rtcdata = (struct vm_rtc_data *)data;
error = vrtc_nvram_read(vm, rtcdata->offset,
&rtcdata->value);
break;
- case VM_RTC_SETTIME:
+ }
+ case VM_RTC_SETTIME: {
+ struct vm_rtc_time *rtctime;
+
rtctime = (struct vm_rtc_time *)data;
error = vrtc_set_time(vm, rtctime->secs);
break;
- case VM_RTC_GETTIME:
- error = 0;
+ }
+ case VM_RTC_GETTIME: {
+ struct vm_rtc_time *rtctime;
+
rtctime = (struct vm_rtc_time *)data;
rtctime->secs = vrtc_get_time(vm);
break;
+ }
case VM_RESTART_INSTRUCTION:
error = vm_restart_instruction(vcpu);
break;
#ifdef BHYVE_SNAPSHOT
- case VM_SNAPSHOT_REQ:
+ case VM_SNAPSHOT_REQ: {
+ struct vm_snapshot_meta *snapshot_meta;
+
snapshot_meta = (struct vm_snapshot_meta *)data;
error = vm_snapshot_req(vm, snapshot_meta);
break;
+ }
#ifdef COMPAT_FREEBSD13
- case VM_SNAPSHOT_REQ_13:
+ case VM_SNAPSHOT_REQ_13: {
+ struct vm_snapshot_meta *snapshot_meta;
+ struct vm_snapshot_meta_13 *snapshot_13;
+
/*
* The old structure just has an additional pointer at
* the start that is ignored.
@@ -513,6 +581,7 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
(struct vm_snapshot_meta *)&snapshot_13->dev_data;
error = vm_snapshot_req(vm, snapshot_meta);
break;
+ }
#endif
case VM_RESTORE_TIME:
error = vm_restore_time(vm);
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index ea6437f320ce..881c4fcff475 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -106,7 +106,7 @@ struct sysentvec elf32_freebsd_sysvec = {
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
-static Elf32_Brandinfo freebsd_brand_info = {
+static const Elf32_Brandinfo freebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_ARM,
.compat_3_brand = "FreeBSD",
@@ -118,7 +118,7 @@ static Elf32_Brandinfo freebsd_brand_info = {
.header_supported= elf32_arm_abi_supported,
};
-SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
+C_SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info);
diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC
index 7394f3842d43..22bb75993834 100644
--- a/sys/arm/conf/GENERIC
+++ b/sys/arm/conf/GENERIC
@@ -270,7 +270,3 @@ makeoptions MODULES_EXTRA+="dtb/nvidia"
makeoptions MODULES_EXTRA+="dtb/rockchip"
makeoptions MODULES_EXTRA+="dtb/rpi"
makeoptions MODULES_EXTRA+="dtb/zynq"
-
-# SOC-specific modules
-makeoptions MODULES_EXTRA+="allwinner"
-makeoptions MODULES_EXTRA+="imx"
diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES
index 920d721dc3ba..2bd41d911124 100644
--- a/sys/arm/conf/NOTES
+++ b/sys/arm/conf/NOTES
@@ -92,11 +92,6 @@ nodevice mps
nodevice bnxt
-# Build SOC-specific modules...
-
-makeoptions MODULES_EXTRA+="allwinner"
-makeoptions MODULES_EXTRA+="imx"
-
# Build dtb files...
makeoptions MODULES_EXTRA+="dtb/allwinner"
diff --git a/sys/arm/include/ieeefp.h b/sys/arm/include/ieeefp.h
index 57dd058b8a95..57719b883d58 100644
--- a/sys/arm/include/ieeefp.h
+++ b/sys/arm/include/ieeefp.h
@@ -49,4 +49,14 @@ typedef enum {
#define fp_except_t int
+/* Augment the userland declarations. */
+__BEGIN_DECLS
+extern fp_rnd_t fpgetround(void);
+extern fp_rnd_t fpsetround(fp_rnd_t);
+extern fp_except_t fpgetmask(void);
+extern fp_except_t fpsetmask(fp_except_t);
+extern fp_except_t fpgetsticky(void);
+extern fp_except_t fpsetsticky(fp_except_t);
+__END_DECLS
+
#endif /* _MACHINE_IEEEFP_H_ */
diff --git a/sys/arm/ti/clk/ti_clkctrl.c b/sys/arm/ti/clk/ti_clkctrl.c
index 72fa8548d4f8..06e558d140f2 100644
--- a/sys/arm/ti/clk/ti_clkctrl.c
+++ b/sys/arm/ti/clk/ti_clkctrl.c
@@ -284,9 +284,9 @@ create_clkctrl(struct ti_clkctrl_softc *sc, cell_t *reg, uint32_t index, uint32_
/*
* Check out XX_CLKCTRL-INDEX(offset)-macro dance in
- * sys/gnu/dts/dts/include/dt-bindings/clock/am3.h
- * sys/gnu/dts/dts/include/dt-bindings/clock/am4.h
- * sys/gnu/dts/dts/include/dt-bindings/clock/dra7.h
+ * sys/contrib/device-tree/include/dt-bindings/clock/am3.h
+ * sys/contrib/device-tree/include/dt-bindings/clock/am4.h
+ * sys/contrib/device-tree/include/dt-bindings/clock/dra7.h
* reg[0] are in practice the same as the offset described in the dts.
*/
/* special_gdbclk_reg are 0 or 1 */
diff --git a/sys/arm/ti/ti_pruss.c b/sys/arm/ti/ti_pruss.c
index 4e9f2022240c..bae1de9f2ddf 100644
--- a/sys/arm/ti/ti_pruss.c
+++ b/sys/arm/ti/ti_pruss.c
@@ -793,6 +793,7 @@ static const struct filterops ti_pruss_kq_read = {
.f_isfd = 1,
.f_detach = ti_pruss_irq_kqread_detach,
.f_event = ti_pruss_irq_kqevent,
+ .f_copy = knote_triv_copy,
};
static void
diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c
index 8f8a934ad520..4cb8ee5f57ef 100644
--- a/sys/arm64/arm64/elf32_machdep.c
+++ b/sys/arm64/arm64/elf32_machdep.c
@@ -210,7 +210,7 @@ freebsd32_fetch_syscall_args(struct thread *td)
sa->code = *ap++;
nap--;
} else if (sa->code == SYS___syscall) {
- sa->code = ap[1];
+ sa->code = ap[_QUAD_LOWWORD];
nap -= 2;
ap += 2;
}
diff --git a/sys/arm64/vmm/vmm.c b/sys/arm64/vmm/vmm.c
index bf52dc0fe916..14ea26c3668c 100644
--- a/sys/arm64/vmm/vmm.c
+++ b/sys/arm64/vmm/vmm.c
@@ -1279,8 +1279,7 @@ vcpu_get_state(struct vcpu *vcpu, int *hostcpu)
int
vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval)
{
-
- if (reg >= VM_REG_LAST)
+ if (reg < 0 || reg >= VM_REG_LAST)
return (EINVAL);
return (vmmops_getreg(vcpu->cookie, reg, retval));
@@ -1291,7 +1290,7 @@ vm_set_register(struct vcpu *vcpu, int reg, uint64_t val)
{
int error;
- if (reg >= VM_REG_LAST)
+ if (reg < 0 || reg >= VM_REG_LAST)
return (EINVAL);
error = vmmops_setreg(vcpu->cookie, reg, val);
if (error || reg != VM_REG_GUEST_PC)
diff --git a/sys/arm64/vmm/vmm_dev_machdep.c b/sys/arm64/vmm/vmm_dev_machdep.c
index 926a74fa528b..29d14e1ba952 100644
--- a/sys/arm64/vmm/vmm_dev_machdep.c
+++ b/sys/arm64/vmm/vmm_dev_machdep.c
@@ -68,19 +68,13 @@ int
vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
int fflag, struct thread *td)
{
- struct vm_run *vmrun;
- struct vm_vgic_version *vgv;
- struct vm_vgic_descr *vgic;
- struct vm_irq *vi;
- struct vm_exception *vmexc;
- struct vm_gla2gpa *gg;
- struct vm_msi *vmsi;
int error;
error = 0;
switch (cmd) {
case VM_RUN: {
struct vm_exit *vme;
+ struct vm_run *vmrun;
vmrun = (struct vm_run *)data;
vme = vm_exitinfo(vcpu);
@@ -94,41 +88,62 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
break;
break;
}
- case VM_INJECT_EXCEPTION:
+ case VM_INJECT_EXCEPTION: {
+ struct vm_exception *vmexc;
+
vmexc = (struct vm_exception *)data;
error = vm_inject_exception(vcpu, vmexc->esr, vmexc->far);
break;
- case VM_GLA2GPA_NOFAULT:
+ }
+ case VM_GLA2GPA_NOFAULT: {
+ struct vm_gla2gpa *gg;
+
gg = (struct vm_gla2gpa *)data;
error = vm_gla2gpa_nofault(vcpu, &gg->paging, gg->gla,
gg->prot, &gg->gpa, &gg->fault);
KASSERT(error == 0 || error == EFAULT,
("%s: vm_gla2gpa unknown error %d", __func__, error));
break;
- case VM_GET_VGIC_VERSION:
+ }
+ case VM_GET_VGIC_VERSION: {
+ struct vm_vgic_version *vgv;
+
vgv = (struct vm_vgic_version *)data;
/* TODO: Query the vgic driver for this */
vgv->version = 3;
vgv->flags = 0;
error = 0;
break;
- case VM_ATTACH_VGIC:
+ }
+ case VM_ATTACH_VGIC: {
+ struct vm_vgic_descr *vgic;
+
vgic = (struct vm_vgic_descr *)data;
error = vm_attach_vgic(vm, vgic);
break;
- case VM_RAISE_MSI:
+ }
+ case VM_RAISE_MSI: {
+ struct vm_msi *vmsi;
+
vmsi = (struct vm_msi *)data;
error = vm_raise_msi(vm, vmsi->msg, vmsi->addr, vmsi->bus,
vmsi->slot, vmsi->func);
break;
- case VM_ASSERT_IRQ:
+ }
+ case VM_ASSERT_IRQ: {
+ struct vm_irq *vi;
+
vi = (struct vm_irq *)data;
error = vm_assert_irq(vm, vi->irq);
break;
- case VM_DEASSERT_IRQ:
+ }
+ case VM_DEASSERT_IRQ: {
+ struct vm_irq *vi;
+
vi = (struct vm_irq *)data;
error = vm_deassert_irq(vm, vi->irq);
break;
+ }
default:
error = ENOTTY;
break;
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index c3587421c176..b44ab866dfe7 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -206,7 +206,8 @@ static struct cdevsw pass_cdevsw = {
static const struct filterops passread_filtops = {
.f_isfd = 1,
.f_detach = passreadfiltdetach,
- .f_event = passreadfilt
+ .f_event = passreadfilt,
+ .f_copy = knote_triv_copy,
};
static MALLOC_DEFINE(M_SCSIPASS, "scsi_pass", "scsi passthrough buffers");
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 21c78e35dadc..39ce2bcea8f4 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -108,6 +108,7 @@ static const struct filterops targread_filtops = {
.f_isfd = 1,
.f_detach = targreadfiltdetach,
.f_event = targreadfilt,
+ .f_copy = knote_triv_copy,
};
static struct cdevsw targ_cdevsw = {
diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
index e88791659f1f..fc3ef7c3e90a 100644
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -104,7 +104,7 @@ static int
epoll_create_common(struct thread *td, int flags)
{
- return (kern_kqueue(td, flags, NULL));
+ return (kern_kqueue(td, flags, false, NULL));
}
#ifdef LINUX_LEGACY_SYSCALLS
diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h
index ccc25bc919ab..8345b7e4b719 100644
--- a/sys/compat/linux/linux_ioctl.h
+++ b/sys/compat/linux/linux_ioctl.h
@@ -823,4 +823,16 @@ int linux32_ioctl_register_handler(struct linux_ioctl_handler *h);
int linux32_ioctl_unregister_handler(struct linux_ioctl_handler *h);
#endif
+#define LINUX_IOCTL_SET(n, low, high) \
+static linux_ioctl_function_t n##_linux_ioctl; \
+static struct linux_ioctl_handler n##_linux_handler = { \
+ n##_linux_ioctl, \
+ low, \
+ high \
+}; \
+SYSINIT(n##_ioctl_register, SI_SUB_KLD, SI_ORDER_MIDDLE, \
+ linux_ioctl_register_handler, &n##_linux_handler); \
+SYSUNINIT(n##_ioctl_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE, \
+ linux_ioctl_unregister_handler, &n##_linux_handler)
+
#endif /* !_LINUX_IOCTL_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h
index 00dd1f9a1ec0..a5a7abd55287 100644
--- a/sys/compat/linuxkpi/common/include/linux/bitops.h
+++ b/sys/compat/linuxkpi/common/include/linux/bitops.h
@@ -37,13 +37,8 @@
#define BIT(nr) (1UL << (nr))
#define BIT_ULL(nr) (1ULL << (nr))
-#ifdef __LP64__
-#define BITS_PER_LONG 64
-#else
-#define BITS_PER_LONG 32
-#endif
-
-#define BITS_PER_LONG_LONG 64
+#define BITS_PER_LONG (__SIZEOF_LONG__ * __CHAR_BIT__)
+#define BITS_PER_LONG_LONG (__SIZEOF_LONG_LONG__ * __CHAR_BIT__)
#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
#define BITMAP_LAST_WORD_MASK(n) (~0UL >> (BITS_PER_LONG - (n)))
diff --git a/sys/compat/linuxkpi/common/include/linux/compiler.h b/sys/compat/linuxkpi/common/include/linux/compiler.h
index 948396144ad6..4146c829b936 100644
--- a/sys/compat/linuxkpi/common/include/linux/compiler.h
+++ b/sys/compat/linuxkpi/common/include/linux/compiler.h
@@ -31,6 +31,7 @@
#define _LINUXKPI_LINUX_COMPILER_H_
#include <sys/cdefs.h>
+#include <sys/endian.h>
#define __user
#define __kernel
@@ -79,6 +80,13 @@
#else
#define __counted_by(_x)
#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define __counted_by_le(_x) __counted_by(_x)
+#define __counted_by_be(_x)
+#else
+#define __counted_by_le(_x)
+#define __counted_by_be(_x) __counted_by(_x)
+#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index 7dd6340746d2..c291133e2e0b 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -92,6 +92,7 @@ struct device_driver {
const struct dev_pm_ops *pm;
void (*shutdown) (struct device *);
+ void (*coredump) (struct device *);
};
struct device_type {
diff --git a/sys/compat/linuxkpi/common/include/linux/etherdevice.h b/sys/compat/linuxkpi/common/include/linux/etherdevice.h
index 1f2d6cf22d7e..b9a4951de8ac 100644
--- a/sys/compat/linuxkpi/common/include/linux/etherdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/etherdevice.h
@@ -27,6 +27,8 @@
#include <linux/types.h>
#include <linux/device.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
#include <sys/random.h>
#include <sys/libkern.h>
@@ -137,4 +139,25 @@ device_get_mac_address(struct device *dev, char *dst)
return (-ENOENT);
}
+/* Returns network byte order. */
+static inline uint16_t
+eth_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (htons(ETHERTYPE_8023));
+}
+
+static inline void
+eth_hw_addr_set(struct net_device *dev, const u8 *addr)
+{
+ pr_debug("%s: TODO (if we want to)\n", __func__);
+}
+
+static inline int
+eth_platform_get_mac_address(struct device *dev __unused, u8 *addr __unused)
+{
+ pr_debug("%s: TODO\n", __func__);
+ return (-ENODEV);
+}
+
#endif /* _LINUXKPI_LINUX_ETHERDEVICE_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/fips.h b/sys/compat/linuxkpi/common/include/linux/fips.h
new file mode 100644
index 000000000000..25c0c1fc1fa0
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/fips.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_FIPS_H
+#define _LINUXKPI_LINUX_FIPS_H
+
+#define fips_enabled 0
+
+#endif /* _LINUXKPI_LINUX_FIPS_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index 17041bb03ce8..ea8c0fc8ef5e 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -312,6 +312,7 @@ enum ieee80211_ac_numbers {
#define IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS 0xf
#define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP 0x0060
#define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME 1
+#define IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT 0x2000
struct ieee80211_mcs_info {
uint8_t rx_mask[IEEE80211_HT_MCS_MASK_LEN];
@@ -365,6 +366,7 @@ enum ieee80211_chanctx_change_flags {
IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(4),
IEEE80211_CHANCTX_CHANGE_PUNCTURING = BIT(5),
IEEE80211_CHANCTX_CHANGE_MIN_DEF = BIT(6),
+ IEEE80211_CHANCTX_CHANGE_AP = BIT(7),
};
enum ieee80211_frame_release_type {
diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h
index 3b808a4a1749..cf27753bcb80 100644
--- a/sys/compat/linuxkpi/common/include/linux/netdevice.h
+++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h
@@ -486,6 +486,21 @@ netdev_priv(const struct net_device *ndev)
}
/* -------------------------------------------------------------------------- */
+
+static __inline void
+netif_device_attach(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static __inline void
+netif_device_detach(struct net_device *ndev)
+{
+ pr_debug("%s: TODO\n", __func__);
+}
+
+
+/* -------------------------------------------------------------------------- */
/* This is really rtnetlink and probably belongs elsewhere. */
#define rtnl_lock() do { } while(0)
diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h b/sys/compat/linuxkpi/common/include/linux/nl80211.h
index f3979d3a2abc..845ffec4bcba 100644
--- a/sys/compat/linuxkpi/common/include/linux/nl80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h
@@ -50,6 +50,7 @@ enum nl80211_feature_flags {
NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = BIT(15),
NL80211_FEATURE_AP_SCAN = BIT(16),
NL80211_FEATURE_ACTIVE_MONITOR = BIT(17),
+ NL80211_FEATURE_SAE = BIT(18),
};
enum nl80211_pmsr_ftm_failure_flags {
@@ -85,6 +86,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_6GHZ_AFC_CLIENT = BIT(15),
NL80211_RRF_PSD = BIT(16),
NL80211_RRF_ALLOW_6GHZ_VLP_AP = BIT(17),
+ NL80211_RRF_ALLOW_20MHZ_ACTIVITY = BIT(18),
};
#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS|NL80211_RRF_NO_HT40PLUS)
@@ -434,6 +436,14 @@ enum nl80211_hidden_ssid {
NL80211_HIDDEN_SSID_NOT_IN_USE,
};
+enum nl80211_external_auth_action {
+ NL80211_EXTERNAL_AUTH_START,
+};
+
+enum nl80211_rxmgmt_flags {
+ NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = BIT(1),
+};
+
#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index ffc2be600c22..06336bf963d6 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -832,6 +832,19 @@ lkpi_pci_restore_state(struct pci_dev *pdev)
#define pci_restore_state(dev) lkpi_pci_restore_state(dev)
static inline int
+linuxkpi_pci_enable_wake(struct pci_dev *pdev, pci_power_t state, bool ena)
+{
+ /*
+ * We do not currently support this in device.h either to
+ * check if the device is allowed to wake up in first place.
+ */
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+#define pci_enable_wake(dev, state, ena) \
+ linuxkpi_pci_enable_wake(dev, state, ena)
+
+static inline int
pci_reset_function(struct pci_dev *pdev)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/platform_device.h b/sys/compat/linuxkpi/common/include/linux/platform_device.h
index 6853e709cb70..dba79f5936cc 100644
--- a/sys/compat/linuxkpi/common/include/linux/platform_device.h
+++ b/sys/compat/linuxkpi/common/include/linux/platform_device.h
@@ -39,7 +39,7 @@ struct platform_device {
};
struct platform_driver {
- int (*remove)(struct platform_device *);
+ void (*remove)(struct platform_device *);
struct device_driver driver;
};
diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h
index 6e41c368a8b8..2e560a120e41 100644
--- a/sys/compat/linuxkpi/common/include/linux/skbuff.h
+++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h
@@ -1159,6 +1159,9 @@ skb_cow_head(struct sk_buff *skb, unsigned int headroom)
return (-1);
}
+/* Misplaced here really but sock comes from skbuff. */
+#define sk_pacing_shift_update(sock, n)
+
#define SKB_WITH_OVERHEAD(_s) \
(_s) - ALIGN(sizeof(struct skb_shared_info), CACHE_LINE_SIZE)
diff --git a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
index 903053e7f6e8..9f3a1ee4c139 100644
--- a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
+++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
@@ -1,54 +1,36 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2022-2023 Bjoern A. Zeeb
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * Copyright (c) 2022-2025 Bjoern A. Zeeb
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H
#define _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H
+#include <linux/kernel.h> /* pr_debug */
+
struct mtk_wed_device {
};
#define WED_WO_STA_REC 0x6
-#define mtk_wed_device_start(_dev, _mask) do { } while(0)
-#define mtk_wed_device_detach(_dev) do { } while(0)
+#define mtk_wed_device_start(_dev, _mask) do { pr_debug("%s: TODO\n", __func__); } while(0)
+#define mtk_wed_device_detach(_dev) do { pr_debug("%s: TODO\n", __func__); } while(0)
#define mtk_wed_device_irq_get(_dev, _mask) 0
-#define mtk_wed_device_irq_set_mask(_dev, _mask) do { } while(0)
-#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) (-ENODEV)
-#define mtk_wed_device_dma_reset(_dev) do {} while (0)
+#define mtk_wed_device_irq_set_mask(_dev, _mask) do { pr_debug("%s: TODO\n", __func__); } while(0)
+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) ({ pr_debug("%s: TODO\n", __func__); -ENODEV; })
+#define mtk_wed_device_dma_reset(_dev) do { pr_debug("%s: TODO\n", __func__); } while (0)
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _entry) \
- do {} while (0)
-#define mtk_wed_device_stop(_dev) do { } while(0)
-#define mtk_wed_device_start_hw_rro(_dev, _mask, _b) do { } while(0)
-#define mtk_wed_device_setup_tc(_dev, _ndev, _type, _tdata) (-EOPNOTSUPP)
+ do { pr_debug("%s: TODO\n", __func__); } while (0)
+#define mtk_wed_device_stop(_dev) do { pr_debug("%s: TODO\n", __func__); } while(0)
+#define mtk_wed_device_start_hw_rro(_dev, _mask, _b) do { pr_debug("%s: TODO\n", __func__); } while(0)
+#define mtk_wed_device_setup_tc(_dev, _ndev, _type, _tdata) ({ pr_debug("%s: TODO\n", __func__); -EOPNOTSUPP; })
static inline bool
mtk_wed_device_active(struct mtk_wed_device *dev __unused)
{
+ pr_debug("%s: TODO\n", __func__);
return (false);
}
@@ -56,6 +38,7 @@ static inline bool
mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
{
+ pr_debug("%s: TODO\n", __func__);
return (false);
}
diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index 239b4a5ae7b8..f769cfdd4075 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -56,7 +56,7 @@ extern int linuxkpi_debug_80211;
#define D80211_IMPROVE 0x2
#endif
#define TODO(fmt, ...) if (linuxkpi_debug_80211 & D80211_TODO) \
- printf("%s:%d: XXX LKPI80211 TODO " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
+ printf("%s:%d: XXX LKPI80211 TODO " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
#define IMPROVE(fmt, ...) if (linuxkpi_debug_80211 & D80211_IMPROVE) \
printf("%s:%d: XXX LKPI80211 IMPROVE " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
@@ -260,6 +260,19 @@ enum ieee80211_vht_opmode {
IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT = 4,
};
+struct cfg80211_bss_ies {
+ uint8_t *data;
+ size_t len;
+};
+
+struct cfg80211_bss {
+ /* XXX TODO */
+ struct cfg80211_bss_ies *ies;
+ struct cfg80211_bss_ies *beacon_ies;
+ uint64_t ts_boottime;
+ int32_t signal;
+};
+
struct cfg80211_connect_resp_params {
/* XXX TODO */
uint8_t *bssid;
@@ -267,7 +280,13 @@ struct cfg80211_connect_resp_params {
const uint8_t *resp_ie;
uint32_t req_ie_len;
uint32_t resp_ie_len;
- int status;
+ int status;
+ struct {
+ const uint8_t *addr;
+ const uint8_t *bssid;
+ struct cfg80211_bss *bss;
+ uint16_t status;
+ } links[IEEE80211_MLD_MAX_NUM_LINKS];
};
struct cfg80211_inform_bss {
@@ -284,19 +303,12 @@ struct cfg80211_roam_info {
uint32_t req_ie_len;
uint32_t resp_ie_len;
struct linuxkpi_ieee80211_channel *channel;
-};
-
-struct cfg80211_bss_ies {
- uint8_t *data;
- size_t len;
-};
-
-struct cfg80211_bss {
- /* XXX TODO */
- struct cfg80211_bss_ies *ies;
- struct cfg80211_bss_ies *beacon_ies;
-
- int32_t signal;
+ struct {
+ const uint8_t *addr;
+ const uint8_t *bssid;
+ struct cfg80211_bss *bss;
+ struct linuxkpi_ieee80211_channel *channel;
+ } links[IEEE80211_MLD_MAX_NUM_LINKS];
};
struct cfg80211_chan_def {
@@ -404,6 +416,7 @@ struct cfg80211_scan_request {
bool no_cck;
bool scan_6ghz;
bool duration_mandatory;
+ bool first_part;
int8_t tsf_report_link_id;
uint16_t duration;
uint32_t flags;
@@ -463,6 +476,24 @@ struct cfg80211_beacon_data {
uint32_t assocresp_ies_len;
};
+struct cfg80211_ap_update {
+ /* XXX TODO */
+ struct cfg80211_beacon_data beacon;
+};
+
+struct cfg80211_crypto_settings {
+ /* XXX TODO */
+ enum nl80211_wpa_versions wpa_versions;
+ uint32_t cipher_group; /* WLAN_CIPHER_SUITE_* */
+ uint32_t *akm_suites;
+ uint32_t *ciphers_pairwise;
+ const uint8_t *sae_pwd;
+ const uint8_t *psk;
+ int n_akm_suites;
+ int n_ciphers_pairwise;
+ int sae_pwd_len;
+};
+
struct cfg80211_ap_settings {
/* XXX TODO */
int auth_type, beacon_interval, dtim_period, hidden_ssid, inactivity_timeout;
@@ -470,6 +501,7 @@ struct cfg80211_ap_settings {
size_t ssid_len;
struct cfg80211_beacon_data beacon;
struct cfg80211_chan_def chandef;
+ struct cfg80211_crypto_settings crypto;
};
struct cfg80211_bss_selection {
@@ -484,23 +516,12 @@ struct cfg80211_bss_selection {
} param;
};
-struct cfg80211_crypto { /* XXX made up name */
- /* XXX TODO */
- enum nl80211_wpa_versions wpa_versions;
- uint32_t cipher_group; /* WLAN_CIPHER_SUITE_* */
- uint32_t *akm_suites;
- uint32_t *ciphers_pairwise;
- const uint8_t *sae_pwd;
- const uint8_t *psk;
- int n_akm_suites;
- int n_ciphers_pairwise;
- int sae_pwd_len;
-};
-
struct cfg80211_connect_params {
/* XXX TODO */
struct linuxkpi_ieee80211_channel *channel;
+ struct linuxkpi_ieee80211_channel *channel_hint;
uint8_t *bssid;
+ uint8_t *bssid_hint;
const uint8_t *ie;
const uint8_t *ssid;
uint32_t ie_len;
@@ -509,7 +530,7 @@ struct cfg80211_connect_params {
uint32_t key_len;
int auth_type, key_idx, privacy, want_1x;
struct cfg80211_bss_selection bss_select;
- struct cfg80211_crypto crypto;
+ struct cfg80211_crypto_settings crypto;
};
enum bss_param_flags { /* Used as bitflags. XXX FIXME values? */
@@ -538,6 +559,14 @@ struct cfg80211_mgmt_tx_params {
int wait;
};
+struct cfg80211_external_auth_params {
+ uint8_t bssid[ETH_ALEN];
+ uint16_t status;
+ enum nl80211_external_auth_action action;
+ unsigned int key_mgmt_suite;
+ struct cfg80211_ssid ssid;
+};
+
struct cfg80211_pmk_conf {
/* XXX TODO */
const uint8_t *pmk;
@@ -548,6 +577,8 @@ struct cfg80211_pmksa {
/* XXX TODO */
const uint8_t *bssid;
const uint8_t *pmkid;
+ const uint8_t *ssid;
+ size_t ssid_len;
};
struct station_del_parameters {
@@ -961,6 +992,27 @@ struct cfg80211_set_hw_timestamp {
bool enable;
};
+struct survey_info { /* net80211::struct ieee80211_channel_survey */
+ /* TODO FIXME */
+ uint32_t filled;
+#define SURVEY_INFO_TIME 0x0001
+#define SURVEY_INFO_TIME_RX 0x0002
+#define SURVEY_INFO_TIME_SCAN 0x0004
+#define SURVEY_INFO_TIME_TX 0x0008
+#define SURVEY_INFO_TIME_BSS_RX 0x0010
+#define SURVEY_INFO_TIME_BUSY 0x0020
+#define SURVEY_INFO_IN_USE 0x0040
+#define SURVEY_INFO_NOISE_DBM 0x0080
+ uint32_t noise;
+ uint64_t time;
+ uint64_t time_bss_rx;
+ uint64_t time_busy;
+ uint64_t time_rx;
+ uint64_t time_scan;
+ uint64_t time_tx;
+ struct linuxkpi_ieee80211_channel *channel;
+};
+
enum wiphy_vendor_cmd_need_flags {
WIPHY_VENDOR_CMD_NEED_NETDEV = 0x01,
WIPHY_VENDOR_CMD_NEED_RUNNING = 0x02,
@@ -1118,49 +1170,53 @@ struct wireless_dev {
struct cfg80211_ops {
/* XXX TODO */
struct wireless_dev *(*add_virtual_intf)(struct wiphy *, const char *, unsigned char, enum nl80211_iftype, struct vif_params *);
- int (*del_virtual_intf)(struct wiphy *, struct wireless_dev *);
- s32 (*change_virtual_intf)(struct wiphy *, struct net_device *, enum nl80211_iftype, struct vif_params *);
- s32 (*scan)(struct wiphy *, struct cfg80211_scan_request *);
- s32 (*set_wiphy_params)(struct wiphy *, u32);
- s32 (*join_ibss)(struct wiphy *, struct net_device *, struct cfg80211_ibss_params *);
- s32 (*leave_ibss)(struct wiphy *, struct net_device *);
- s32 (*get_station)(struct wiphy *, struct net_device *, const u8 *, struct station_info *);
- int (*dump_station)(struct wiphy *, struct net_device *, int, u8 *, struct station_info *);
- s32 (*set_tx_power)(struct wiphy *, struct wireless_dev *, enum nl80211_tx_power_setting, s32);
- s32 (*get_tx_power)(struct wiphy *, struct wireless_dev *, s32 *);
- s32 (*add_key)(struct wiphy *, struct net_device *, u8, bool, const u8 *, struct key_params *);
- s32 (*del_key)(struct wiphy *, struct net_device *, u8, bool, const u8 *);
- s32 (*get_key)(struct wiphy *, struct net_device *, u8, bool, const u8 *, void *, void(*)(void *, struct key_params *));
- s32 (*set_default_key)(struct wiphy *, struct net_device *, u8, bool, bool);
- s32 (*set_default_mgmt_key)(struct wiphy *, struct net_device *, u8);
- s32 (*set_power_mgmt)(struct wiphy *, struct net_device *, bool, s32);
- s32 (*connect)(struct wiphy *, struct net_device *, struct cfg80211_connect_params *);
- s32 (*disconnect)(struct wiphy *, struct net_device *, u16);
- s32 (*suspend)(struct wiphy *, struct cfg80211_wowlan *);
- s32 (*resume)(struct wiphy *);
- s32 (*set_pmksa)(struct wiphy *, struct net_device *, struct cfg80211_pmksa *);
- s32 (*del_pmksa)(struct wiphy *, struct net_device *, struct cfg80211_pmksa *);
- s32 (*flush_pmksa)(struct wiphy *, struct net_device *);
- s32 (*start_ap)(struct wiphy *, struct net_device *, struct cfg80211_ap_settings *);
- int (*stop_ap)(struct wiphy *, struct net_device *);
- s32 (*change_beacon)(struct wiphy *, struct net_device *, struct cfg80211_beacon_data *);
- int (*del_station)(struct wiphy *, struct net_device *, struct station_del_parameters *);
- int (*change_station)(struct wiphy *, struct net_device *, const u8 *, struct station_parameters *);
+ int (*del_virtual_intf)(struct wiphy *, struct wireless_dev *);
+ int (*change_virtual_intf)(struct wiphy *, struct net_device *, enum nl80211_iftype, struct vif_params *);
+ int (*scan)(struct wiphy *, struct cfg80211_scan_request *);
+ int (*set_wiphy_params)(struct wiphy *, int, uint32_t);
+ int (*join_ibss)(struct wiphy *, struct net_device *, struct cfg80211_ibss_params *);
+ int (*leave_ibss)(struct wiphy *, struct net_device *);
+ int (*get_station)(struct wiphy *, struct net_device *, const uint8_t *, struct station_info *);
+ int (*dump_station)(struct wiphy *, struct net_device *, int, uint8_t *, struct station_info *);
+ int (*set_tx_power)(struct wiphy *, struct wireless_dev *, int, enum nl80211_tx_power_setting, int);
+ int (*get_tx_power)(struct wiphy *, struct wireless_dev *, int, unsigned int, int *);
+ int (*add_key)(struct wiphy *, struct net_device *, int, uint8_t, bool, const uint8_t *, struct key_params *);
+ int (*del_key)(struct wiphy *, struct net_device *, int, uint8_t, bool, const uint8_t *);
+ int (*get_key)(struct wiphy *, struct net_device *, int, uint8_t, bool, const uint8_t *, void *, void(*)(void *, struct key_params *));
+ int (*set_default_key)(struct wiphy *, struct net_device *, int, uint8_t, bool, bool);
+ int (*set_default_mgmt_key)(struct wiphy *, struct net_device *, int, uint8_t);
+ int (*set_power_mgmt)(struct wiphy *, struct net_device *, bool, int);
+ int (*connect)(struct wiphy *, struct net_device *, struct cfg80211_connect_params *);
+ int (*disconnect)(struct wiphy *, struct net_device *, uint16_t);
+ int (*suspend)(struct wiphy *, struct cfg80211_wowlan *);
+ int (*resume)(struct wiphy *);
+ int (*set_pmksa)(struct wiphy *, struct net_device *, struct cfg80211_pmksa *);
+ int (*del_pmksa)(struct wiphy *, struct net_device *, struct cfg80211_pmksa *);
+ int (*flush_pmksa)(struct wiphy *, struct net_device *);
+ int (*start_ap)(struct wiphy *, struct net_device *, struct cfg80211_ap_settings *);
+ int (*stop_ap)(struct wiphy *, struct net_device *, unsigned int);
+ int (*change_beacon)(struct wiphy *, struct net_device *, struct cfg80211_ap_update *);
+ int (*del_station)(struct wiphy *, struct net_device *, struct station_del_parameters *);
+ int (*change_station)(struct wiphy *, struct net_device *, const uint8_t *, struct station_parameters *);
int (*sched_scan_start)(struct wiphy *, struct net_device *, struct cfg80211_sched_scan_request *);
- int (*sched_scan_stop)(struct wiphy *, struct net_device *, u64);
+ int (*sched_scan_stop)(struct wiphy *, struct net_device *, uint64_t);
void (*update_mgmt_frame_registrations)(struct wiphy *, struct wireless_dev *, struct mgmt_frame_regs *);
- int (*mgmt_tx)(struct wiphy *, struct wireless_dev *, struct cfg80211_mgmt_tx_params *, u64 *);
- int (*cancel_remain_on_channel)(struct wiphy *, struct wireless_dev *, u64);
- int (*get_channel)(struct wiphy *, struct wireless_dev *, struct cfg80211_chan_def *);
- int (*crit_proto_start)(struct wiphy *, struct wireless_dev *, enum nl80211_crit_proto_id, u16);
+ int (*mgmt_tx)(struct wiphy *, struct wireless_dev *, struct cfg80211_mgmt_tx_params *, uint64_t *);
+ int (*cancel_remain_on_channel)(struct wiphy *, struct wireless_dev *, uint64_t);
+ int (*get_channel)(struct wiphy *, struct wireless_dev *, unsigned int, struct cfg80211_chan_def *);
+ int (*crit_proto_start)(struct wiphy *, struct wireless_dev *, enum nl80211_crit_proto_id, uint16_t);
void (*crit_proto_stop)(struct wiphy *, struct wireless_dev *);
- int (*tdls_oper)(struct wiphy *, struct net_device *, const u8 *, enum nl80211_tdls_operation);
- int (*update_connect_params)(struct wiphy *, struct net_device *, struct cfg80211_connect_params *, u32);
- int (*set_pmk)(struct wiphy *, struct net_device *, const struct cfg80211_pmk_conf *);
- int (*del_pmk)(struct wiphy *, struct net_device *, const u8 *);
- int (*remain_on_channel)(struct wiphy *, struct wireless_dev *, struct linuxkpi_ieee80211_channel *, unsigned int, u64 *);
- int (*start_p2p_device)(struct wiphy *, struct wireless_dev *);
- void (*stop_p2p_device)(struct wiphy *, struct wireless_dev *);
+ int (*tdls_oper)(struct wiphy *, struct net_device *, const uint8_t *, enum nl80211_tdls_operation);
+ int (*update_connect_params)(struct wiphy *, struct net_device *, struct cfg80211_connect_params *, uint32_t);
+ int (*set_pmk)(struct wiphy *, struct net_device *, const struct cfg80211_pmk_conf *);
+ int (*del_pmk)(struct wiphy *, struct net_device *, const uint8_t *);
+ int (*remain_on_channel)(struct wiphy *, struct wireless_dev *, struct linuxkpi_ieee80211_channel *, unsigned int, uint64_t *);
+ int (*start_p2p_device)(struct wiphy *, struct wireless_dev *);
+ void (*stop_p2p_device)(struct wiphy *, struct wireless_dev *);
+ int (*dump_survey)(struct wiphy *, struct net_device *, int, struct survey_info *);
+ int (*external_auth)(struct wiphy *, struct net_device *, struct cfg80211_external_auth_params *);
+ int (*set_cqm_rssi_range_config)(struct wiphy *, struct net_device *, int, int);
+
};
@@ -1179,6 +1235,8 @@ void linuxkpi_wiphy_delayed_work_queue(struct wiphy *,
struct wiphy_delayed_work *, unsigned long);
void linuxkpi_wiphy_delayed_work_cancel(struct wiphy *,
struct wiphy_delayed_work *);
+void linuxkpi_wiphy_delayed_work_flush(struct wiphy *,
+ struct wiphy_delayed_work *);
int linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
struct linuxkpi_ieee80211_regdomain *regd);
@@ -1247,6 +1305,21 @@ wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked,
/* -------------------------------------------------------------------------- */
+static inline int
+cfg80211_register_netdevice(struct net_device *ndev)
+{
+ TODO();
+ return (-ENXIO);
+}
+
+static inline void
+cfg80211_unregister_netdevice(struct net_device *ndev)
+{
+ TODO();
+}
+
+/* -------------------------------------------------------------------------- */
+
static inline struct cfg80211_bss *
cfg80211_get_bss(struct wiphy *wiphy, struct linuxkpi_ieee80211_channel *chan,
const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len,
@@ -1309,15 +1382,15 @@ reg_query_regdb_wmm(uint8_t *alpha2, uint32_t center_freq,
return (-ENODATA);
}
-static __inline const u8 *
-cfg80211_find_ie_match(uint32_t f, const u8 *ies, size_t ies_len,
- const u8 *match, int x, int y)
+static __inline const uint8_t *
+cfg80211_find_ie_match(uint32_t f, const uint8_t *ies, size_t ies_len,
+ const uint8_t *match, int x, int y)
{
TODO();
return (NULL);
}
-static __inline const u8 *
+static __inline const uint8_t *
cfg80211_find_ie(uint8_t eid, const uint8_t *ie, uint32_t ielen)
{
TODO();
@@ -1339,6 +1412,36 @@ cfg80211_pmsr_report(struct wireless_dev *wdev,
TODO();
}
+static inline int
+nl80211_chan_width_to_mhz(enum nl80211_chan_width width)
+{
+ switch (width) {
+ case NL80211_CHAN_WIDTH_5:
+ return (5);
+ break;
+ case NL80211_CHAN_WIDTH_10:
+ return (10);
+ break;
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ return (20);
+ break;
+ case NL80211_CHAN_WIDTH_40:
+ return (40);
+ break;
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_80P80:
+ return (80);
+ break;
+ case NL80211_CHAN_WIDTH_160:
+ return (160);
+ break;
+ case NL80211_CHAN_WIDTH_320:
+ return (320);
+ break;
+ }
+}
+
static inline void
cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
struct linuxkpi_ieee80211_channel *chan, enum nl80211_channel_type chan_type)
@@ -1377,6 +1480,12 @@ cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
return (false);
}
+static inline int
+cfg80211_chandef_get_width(const struct cfg80211_chan_def *chandef)
+{
+ return (nl80211_chan_width_to_mhz(chandef->width));
+}
+
static __inline bool
cfg80211_chandef_dfs_usable(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef)
{
@@ -1688,8 +1797,8 @@ cfg80211_disconnected(struct net_device *ndev, uint16_t reason,
}
static __inline int
-cfg80211_get_p2p_attr(const u8 *ie, u32 ie_len,
- enum ieee80211_p2p_attr_ids attr, u8 *p, size_t p_len)
+cfg80211_get_p2p_attr(const uint8_t *ie, uint32_t ie_len,
+ enum ieee80211_p2p_attr_ids attr, uint8_t *p, size_t p_len)
{
TODO();
return (-1);
@@ -1725,13 +1834,13 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
static __inline void
cfg80211_mgmt_tx_status(struct wireless_dev *wdev, uint64_t cookie,
- const u8 *buf, size_t len, bool ack, gfp_t gfp)
+ const uint8_t *buf, size_t len, bool ack, gfp_t gfp)
{
TODO();
}
static __inline void
-cfg80211_michael_mic_failure(struct net_device *ndev, const uint8_t *addr,
+cfg80211_michael_mic_failure(struct net_device *ndev, const uint8_t addr[ETH_ALEN],
enum nl80211_key_type key_type, int _x, void *p, gfp_t gfp)
{
TODO();
@@ -1751,8 +1860,8 @@ cfg80211_del_sta(struct net_device *ndev, const uint8_t *addr, gfp_t gfp)
}
static __inline void
-cfg80211_port_authorized(struct net_device *ndev, const uint8_t *bssid,
- gfp_t gfp)
+cfg80211_port_authorized(struct net_device *ndev, const uint8_t *addr,
+ const uint8_t *bitmap, uint8_t len, gfp_t gfp)
{
TODO();
}
@@ -1935,7 +2044,7 @@ cfg80211_background_radar_event(struct wiphy *wiphy,
TODO();
}
-static __inline const u8 *
+static __inline const uint8_t *
cfg80211_find_ext_ie(uint8_t eid, const uint8_t *p, size_t len)
{
TODO();
@@ -2033,6 +2142,14 @@ cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype iftype)
return (NULL);
}
+static inline int
+cfg80211_external_auth_request(struct net_device *ndev,
+ struct cfg80211_external_auth_params *params, gfp_t gfp)
+{
+ TODO();
+ return (-ENXIO);
+}
+
static inline uint16_t
ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband,
enum nl80211_iftype iftype)
@@ -2041,36 +2158,6 @@ ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband,
return (0);
}
-static inline int
-nl80211_chan_width_to_mhz(enum nl80211_chan_width width)
-{
- switch (width) {
- case NL80211_CHAN_WIDTH_5:
- return (5);
- break;
- case NL80211_CHAN_WIDTH_10:
- return (10);
- break;
- case NL80211_CHAN_WIDTH_20_NOHT:
- case NL80211_CHAN_WIDTH_20:
- return (20);
- break;
- case NL80211_CHAN_WIDTH_40:
- return (40);
- break;
- case NL80211_CHAN_WIDTH_80:
- case NL80211_CHAN_WIDTH_80P80:
- return (80);
- break;
- case NL80211_CHAN_WIDTH_160:
- return (160);
- break;
- case NL80211_CHAN_WIDTH_320:
- return (320);
- break;
- }
-}
-
static __inline ssize_t
wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file,
char *buf, size_t bufsize, const char __user *userbuf, size_t count,
@@ -2093,6 +2180,13 @@ wiphy_locked_debugfs_write(struct wiphy *wiphy, struct file *file,
return (-ENXIO);
}
+static inline void
+cfg80211_cqm_rssi_notify(struct net_device *dev,
+ enum nl80211_cqm_rssi_threshold_event rssi_te, int32_t rssi, gfp_t gfp)
+{
+ TODO();
+}
+
/* -------------------------------------------------------------------------- */
static inline void
@@ -2140,6 +2234,12 @@ wiphy_delayed_work_cancel(struct wiphy *wiphy, struct wiphy_delayed_work *wdwk)
linuxkpi_wiphy_delayed_work_cancel(wiphy, wdwk);
}
+static inline void
+wiphy_delayed_work_flush(struct wiphy *wiphy, struct wiphy_delayed_work *wdwk)
+{
+ linuxkpi_wiphy_delayed_work_flush(wiphy, wdwk);
+}
+
/* -------------------------------------------------------------------------- */
#define wiphy_err(_wiphy, _fmt, ...) \
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index 8de03410c6b6..523836b52a40 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -166,7 +166,7 @@ enum ieee80211_bss_changed {
#define WLAN_AKM_SUITE_PSK_SHA256 WLAN_AKM_SUITE(6)
/* TDLS 7 */
#define WLAN_AKM_SUITE_SAE WLAN_AKM_SUITE(8)
-/* FToSAE 9 */
+#define WLAN_AKM_SUITE_FT_OVER_SAE WLAN_AKM_SUITE(9)
/* AP peer key 10 */
/* 802.1x suite B 11 */
/* 802.1x suite B 384 12 */
@@ -857,7 +857,8 @@ struct ieee80211_vif_chanctx_switch {
};
struct ieee80211_prep_tx_info {
- u16 duration;
+ uint16_t duration;
+ uint16_t subtype;
bool success;
bool was_assoc;
int link_id;
@@ -904,27 +905,6 @@ struct linuxkpi_ieee80211_tim_ie {
};
#define ieee80211_tim_ie linuxkpi_ieee80211_tim_ie
-struct survey_info { /* net80211::struct ieee80211_channel_survey */
- /* TODO FIXME */
- uint32_t filled;
-#define SURVEY_INFO_TIME 0x0001
-#define SURVEY_INFO_TIME_RX 0x0002
-#define SURVEY_INFO_TIME_SCAN 0x0004
-#define SURVEY_INFO_TIME_TX 0x0008
-#define SURVEY_INFO_TIME_BSS_RX 0x0010
-#define SURVEY_INFO_TIME_BUSY 0x0020
-#define SURVEY_INFO_IN_USE 0x0040
-#define SURVEY_INFO_NOISE_DBM 0x0080
- uint32_t noise;
- uint64_t time;
- uint64_t time_bss_rx;
- uint64_t time_busy;
- uint64_t time_rx;
- uint64_t time_scan;
- uint64_t time_tx;
- struct ieee80211_channel *channel;
-};
-
enum ieee80211_iface_iter {
IEEE80211_IFACE_ITER_NORMAL = BIT(0),
IEEE80211_IFACE_ITER_RESUME_ALL = BIT(1),
@@ -1553,6 +1533,15 @@ ieee80211_iter_chan_contexts_atomic(struct ieee80211_hw *hw,
}
static __inline void
+ieee80211_iter_chan_contexts_mtx(struct ieee80211_hw *hw,
+ void (*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *, void *),
+ void *arg)
+{
+ IMPROVE("XXX LKPI80211 TODO MTX\n");
+ linuxkpi_ieee80211_iterate_chan_contexts(hw, iterfunc, arg);
+}
+
+static __inline void
ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
void (*iterfunc)(void *, struct ieee80211_sta *), void *arg)
{
@@ -2063,7 +2052,7 @@ ieee80211_tx_dequeue_ni(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
static __inline void
ieee80211_update_mu_groups(struct ieee80211_vif *vif,
- u_int _i, uint8_t *ms, uint8_t *up)
+ u_int link_id, const uint8_t *ms, const uint8_t *up)
{
TODO();
}
diff --git a/sys/compat/linuxkpi/common/include/net/netmem.h b/sys/compat/linuxkpi/common/include/net/netmem.h
new file mode 100644
index 000000000000..c8de09a2e8c2
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/net/netmem.h
@@ -0,0 +1,21 @@
+/*-
+ * Copyright (c) 2023-2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_NET_NETMEM_H
+#define _LINUXKPI_NET_NETMEM_H
+
+struct page_pool;
+
+struct netmem_desc {
+ struct page_pool *pp;
+};
+
+#define pp_page_to_nmdesc(page) \
+ (_Generic((page), \
+ const struct page *: (const struct netmem_desc *)(page), \
+ struct page *: (struct netmem_desc *)(page)))
+
+#endif /* _LINUXKPI_NET_NETMEM_H */
diff --git a/sys/compat/linuxkpi/common/include/net/page_pool.h b/sys/compat/linuxkpi/common/include/net/page_pool.h
deleted file mode 100644
index 2dc8f74b31f3..000000000000
--- a/sys/compat/linuxkpi/common/include/net/page_pool.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*-
- * Copyright (c) 2023 Bjoern A. Zeeb
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _LINUXKPI_NET_PAGE_POOL_H
-#define _LINUXKPI_NET_PAGE_POOL_H
-
-#include <linux/kernel.h> /* pr_debug */
-#include <linux/types.h>
-#include <linux/dma-mapping.h>
-#include <linux/netdevice.h>
-
-struct device;
-
-struct page_pool_params {
- struct device *dev;
- uint32_t flags;
- uint32_t order;
- uint32_t pool_size;
- uint32_t max_len;
- uint32_t offset;
- int nid; /* NUMA */
- enum dma_data_direction dma_dir;
- struct napi_struct *napi;
-};
-
-struct page_pool {
-};
-
-#define PP_FLAG_DMA_MAP BIT(0)
-#define PP_FLAG_DMA_SYNC_DEV BIT(1)
-#define PP_FLAG_PAGE_FRAG BIT(2)
-
-static inline struct page_pool *
-page_pool_create(const struct page_pool_params *ppparams)
-{
-
- pr_debug("%s: TODO\n", __func__);
- return (NULL);
-}
-
-static inline void
-page_pool_destroy(struct page_pool *ppool)
-{
-
- pr_debug("%s: TODO\n", __func__);
-}
-
-static inline struct page *
-page_pool_dev_alloc_frag(struct page_pool *ppool, uint32_t *offset,
- size_t size)
-{
-
- pr_debug("%s: TODO\n", __func__);
- return (NULL);
-}
-
-static inline dma_addr_t
-page_pool_get_dma_addr(struct page *page)
-{
-
- pr_debug("%s: TODO\n", __func__);
- return (0);
-}
-
-static inline enum dma_data_direction
-page_pool_get_dma_dir(const struct page_pool *ppool)
-{
-
- pr_debug("%s: TODO\n", __func__);
- return (DMA_BIDIRECTIONAL);
-}
-
-static inline void
-page_pool_put_full_page(struct page_pool *ppool, struct page *page,
- bool allow_direct)
-{
-
- pr_debug("%s: TODO\n", __func__);
-}
-
-static inline int
-page_pool_ethtool_stats_get_count(void)
-{
-
- pr_debug("%s: TODO\n", __func__);
- return (0);
-}
-
-static inline uint8_t *
-page_pool_ethtool_stats_get_strings(uint8_t *x)
-{
-
- pr_debug("%s: TODO\n", __func__);
- return (x);
-}
-
-#endif /* _LINUXKPI_NET_PAGE_POOL_H */
diff --git a/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h b/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h
new file mode 100644
index 000000000000..3469c39c7757
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2023-2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_NET_PAGE_POOL_HELPERS_H
+#define _LINUXKPI_NET_PAGE_POOL_HELPERS_H
+
+#include <linux/kernel.h> /* pr_debug */
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <net/page_pool/types.h>
+
+static inline struct page_pool *
+page_pool_create(const struct page_pool_params *ppparams)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline void
+page_pool_destroy(struct page_pool *ppool)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline struct page *
+page_pool_dev_alloc_frag(struct page_pool *ppool, uint32_t *offset,
+ size_t size)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (NULL);
+}
+
+static inline dma_addr_t
+page_pool_get_dma_addr(struct page *page)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+static inline enum dma_data_direction
+page_pool_get_dma_dir(const struct page_pool *ppool)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (DMA_BIDIRECTIONAL);
+}
+
+static inline void
+page_pool_put_full_page(struct page_pool *ppool, struct page *page,
+ bool allow_direct)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+}
+
+static inline int
+page_pool_ethtool_stats_get_count(void)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (0);
+}
+
+static inline uint8_t *
+page_pool_ethtool_stats_get_strings(uint8_t *x)
+{
+
+ pr_debug("%s: TODO\n", __func__);
+ return (x);
+}
+
+#endif /* _LINUXKPI_NET_PAGE_POOL_HELPERS_H */
diff --git a/sys/compat/linuxkpi/common/include/net/page_pool/types.h b/sys/compat/linuxkpi/common/include/net/page_pool/types.h
new file mode 100644
index 000000000000..6747be50b9b2
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/net/page_pool/types.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2023-2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_NET_PAGE_POOL_TYPES_H
+#define _LINUXKPI_NET_PAGE_POOL_TYPES_H
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <net/netmem.h>
+
+struct device;
+struct napi_struct;
+
+struct page_pool_params {
+ struct device *dev;
+ uint32_t flags;
+ uint32_t order;
+ uint32_t pool_size;
+ uint32_t max_len;
+ uint32_t offset;
+ int nid; /* NUMA */
+ enum dma_data_direction dma_dir;
+ struct napi_struct *napi;
+};
+
+struct page_pool {
+};
+
+#define PP_FLAG_DMA_MAP BIT(0)
+#define PP_FLAG_DMA_SYNC_DEV BIT(1)
+#define PP_FLAG_PAGE_FRAG BIT(2)
+
+#endif /* _LINUXKPI_NET_PAGE_POOL_TYPES_H */
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index bc4b334de28e..0dc3b2631804 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -7833,7 +7833,7 @@ lkpi_wiphy_delayed_work_timer(struct timer_list *tl)
struct wiphy_delayed_work *wdwk;
wdwk = timer_container_of(wdwk, tl, timer);
- wiphy_work_queue(wdwk->wiphy, &wdwk->work);
+ wiphy_work_queue(wdwk->wiphy, &wdwk->work);
}
void
@@ -7858,6 +7858,16 @@ linuxkpi_wiphy_delayed_work_cancel(struct wiphy *wiphy,
wiphy_work_cancel(wiphy, &wdwk->work);
}
+void
+linuxkpi_wiphy_delayed_work_flush(struct wiphy *wiphy,
+ struct wiphy_delayed_work *wdwk)
+{
+ lockdep_assert_held(&wiphy->mtx);
+
+ del_timer_sync(&wdwk->timer);
+ wiphy_work_flush(wiphy, &wdwk->work);
+}
+
/* -------------------------------------------------------------------------- */
struct wiphy *
diff --git a/sys/compat/linuxkpi/common/src/linux_80211_macops.c b/sys/compat/linuxkpi/common/src/linux_80211_macops.c
index 1046b753574f..04f9f6d7e7fc 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211_macops.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211_macops.c
@@ -42,7 +42,7 @@
if (linuxkpi_debug_80211 & D80211_TRACE_MO) \
printf("LKPI_80211_TRACE_MO %s:%d: %d %d %lu: " fmt "\n", \
__func__, __LINE__, curcpu, curthread->td_tid, \
- jiffies, __VA_ARGS__)
+ jiffies, ##__VA_ARGS__)
#else
#define LKPI_80211_TRACE_MO(...) do { } while(0)
#endif
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
index 458744a9fec6..ff0f477ea8cc 100644
--- a/sys/compat/linuxkpi/common/src/linux_compat.c
+++ b/sys/compat/linuxkpi/common/src/linux_compat.c
@@ -1171,12 +1171,14 @@ static const struct filterops linux_dev_kqfiltops_read = {
.f_isfd = 1,
.f_detach = linux_file_kqfilter_detach,
.f_event = linux_file_kqfilter_read_event,
+ .f_copy = knote_triv_copy,
};
static const struct filterops linux_dev_kqfiltops_write = {
.f_isfd = 1,
.f_detach = linux_file_kqfilter_detach,
.f_event = linux_file_kqfilter_write_event,
+ .f_copy = knote_triv_copy,
};
static void
diff --git a/sys/conf/dtb.build.mk b/sys/conf/dtb.build.mk
index 7eb0db5e8b80..f0cd8f8d515c 100644
--- a/sys/conf/dtb.build.mk
+++ b/sys/conf/dtb.build.mk
@@ -15,9 +15,10 @@ SYSDIR= ${S}
.endif
.for _dts in ${DTS}
-# DTB for aarch64 needs to preserve the immediate parent of the .dts, because
-# these DTS are vendored and should be installed into their vendored directory.
-.if ${MACHINE_CPUARCH} == "aarch64"
+# DTBs for aarch64 and riscv need to preserve the immediate parent of the .dts,
+# because these DTS are vendored and should be installed into their vendored
+# directories.
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "riscv"
DTB+= ${_dts:R:S/$/.dtb/}
.else
DTB+= ${_dts:T:R:S/$/.dtb/}
@@ -54,7 +55,7 @@ _dtbinstall:
# entries in the NO_ROOT case.
test -d ${DESTDIR}${DTBDIR} || ${INSTALL} -d -o ${DTBOWN} -g ${DTBGRP} ${DESTDIR}${DTBDIR}
.for _dtb in ${DTB}
-.if ${MACHINE_CPUARCH} == "aarch64"
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "riscv"
# :H:T here to grab the vendor component of the DTB path in a way that
# allows out-of-tree DTS builds, too. We make the assumption that
# out-of-tree DTS will have a similar directory structure to in-tree,
diff --git a/sys/conf/files.x86 b/sys/conf/files.x86
index 953da7dd1284..21a1b8046f12 100644
--- a/sys/conf/files.x86
+++ b/sys/conf/files.x86
@@ -311,6 +311,7 @@ dev/ntb/test/ntb_tool.c optional ntb_tool
dev/nvram/nvram.c optional nvram isa
dev/random/ivy.c optional rdrand_rng !random_loadable
dev/random/nehemiah.c optional padlock_rng !random_loadable
+dev/random/rdseed.c optional rdrand_rng !random_loadable
dev/qat_c2xxx/qat.c optional qat_c2xxx
dev/qat_c2xxx/qat_ae.c optional qat_c2xxx
dev/qat_c2xxx/qat_c2xxx.c optional qat_c2xxx
diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
index 1c608348ffcd..422b3e9df388 100755
--- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
+++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
@@ -121,7 +121,14 @@ case "$OS" in
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
;;
freebsd15-0c)
- FreeBSD="15.0-ALPHA3"
+ FreeBSD="15.0-ALPHA4"
+ OSNAME="FreeBSD $FreeBSD"
+ OSv="freebsd14.0"
+ URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
+ KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
+ ;;
+ freebsd16-0c)
+ FreeBSD="16.0-CURRENT"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
@@ -287,7 +294,7 @@ else
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
ssh 2>/dev/null root@vm0 "uname -a" && break
done
- ssh root@vm0 "pkg install -y bash ca_root_nss git qemu-guest-agent python3 py311-cloud-init"
+ ssh root@vm0 "env IGNORE_OSVERSION=yes pkg install -y bash ca_root_nss git qemu-guest-agent python3 py311-cloud-init"
ssh root@vm0 "chsh -s $BASH root"
ssh root@vm0 'sysrc qemu_guest_agent_enable="YES"'
ssh root@vm0 'sysrc cloudinit_enable="YES"'
diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
index 69349678d84c..3b164548f9be 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
@@ -68,7 +68,7 @@ jobs:
# FreeBSD variants of 2025-06:
# FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r
# FreeBSD Stable: freebsd13-5s, freebsd14-3s
- # FreeBSD Current: freebsd15-0c
+ # FreeBSD Current: freebsd15-0c, freebsd16-0c
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
runs-on: ubuntu-24.04
steps:
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index 70a4ed46f263..1ffb8ebc70f2 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -106,11 +106,15 @@ extern boolean_t spa_mode_readable_spacemaps;
extern uint_t zfs_reconstruct_indirect_combinations_max;
extern uint_t zfs_btree_verify_intensity;
+enum {
+ ARG_ALLOCATED = 256,
+ ARG_BLOCK_BIN_MODE,
+ ARG_BLOCK_CLASSES,
+};
+
static const char cmdname[] = "zdb";
uint8_t dump_opt[512];
-#define ALLOCATED_OPT 256
-
typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
static uint64_t *zopt_metaslab = NULL;
@@ -131,6 +135,20 @@ static objset_t *os;
static boolean_t kernel_init_done;
static boolean_t corruption_found = B_FALSE;
+static enum {
+ BIN_AUTO = 0,
+ BIN_PSIZE,
+ BIN_LSIZE,
+ BIN_ASIZE,
+} block_bin_mode = BIN_AUTO;
+
+static enum {
+ CLASS_NORMAL = 1 << 1,
+ CLASS_SPECIAL = 1 << 2,
+ CLASS_DEDUP = 1 << 3,
+ CLASS_OTHER = 1 << 4,
+} block_classes = 0;
+
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t);
static void mos_obj_refd(uint64_t);
@@ -749,6 +767,12 @@ usage(void)
(void) fprintf(stderr, " Options to control amount of output:\n");
(void) fprintf(stderr, " -b --block-stats "
"block statistics\n");
+ (void) fprintf(stderr, " --bin=(lsize|psize|asize) "
+ "bin blocks based on this size in all three columns\n");
+ (void) fprintf(stderr,
+ " --class=(normal|special|dedup|other)[,...]\n"
+ " only consider blocks from "
+ "these allocation classes\n");
(void) fprintf(stderr, " -B --backup "
"backup stream\n");
(void) fprintf(stderr, " -c --checksum "
@@ -1694,7 +1718,7 @@ dump_metaslab(metaslab_t *msp)
(u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
(u_longlong_t)space_map_object(sm), freebuf);
- if (dump_opt[ALLOCATED_OPT] ||
+ if (dump_opt[ARG_ALLOCATED] ||
(dump_opt['m'] > 2 && !dump_opt['L'])) {
mutex_enter(&msp->ms_lock);
VERIFY0(metaslab_load(msp));
@@ -1705,7 +1729,7 @@ dump_metaslab(metaslab_t *msp)
dump_metaslab_stats(msp);
}
- if (dump_opt[ALLOCATED_OPT]) {
+ if (dump_opt[ARG_ALLOCATED]) {
uint64_t off = msp->ms_start;
zfs_range_tree_walk(msp->ms_allocatable, dump_allocated,
&off);
@@ -1726,7 +1750,7 @@ dump_metaslab(metaslab_t *msp)
SPACE_MAP_HISTOGRAM_SIZE, sm->sm_shift);
}
- if (dump_opt[ALLOCATED_OPT] ||
+ if (dump_opt[ARG_ALLOCATED] ||
(dump_opt['m'] > 2 && !dump_opt['L'])) {
metaslab_unload(msp);
mutex_exit(&msp->ms_lock);
@@ -5814,6 +5838,34 @@ dump_size_histograms(zdb_cb_t *zcb)
(void) printf("\nBlock Size Histogram\n");
+ switch (block_bin_mode) {
+ case BIN_PSIZE:
+ printf("(note: all categories are binned by %s)\n", "psize");
+ break;
+ case BIN_LSIZE:
+ printf("(note: all categories are binned by %s)\n", "lsize");
+ break;
+ case BIN_ASIZE:
+ printf("(note: all categories are binned by %s)\n", "asize");
+ break;
+ default:
+ printf("(note: all categories are binned separately)\n");
+ break;
+ }
+ if (block_classes != 0) {
+ char buf[256] = "";
+ if (block_classes & CLASS_NORMAL)
+ strlcat(buf, "\"normal\", ", sizeof (buf));
+ if (block_classes & CLASS_SPECIAL)
+ strlcat(buf, "\"special\", ", sizeof (buf));
+ if (block_classes & CLASS_DEDUP)
+ strlcat(buf, "\"dedup\", ", sizeof (buf));
+ if (block_classes & CLASS_OTHER)
+ strlcat(buf, "\"other\", ", sizeof (buf));
+ buf[strlen(buf)-2] = '\0';
+ printf("(note: only blocks in these classes are counted: %s)\n",
+ buf);
+ }
/*
* Print the first line titles
*/
@@ -6162,29 +6214,85 @@ skipped:
[BPE_GET_PSIZE(bp)]++;
return;
}
+
+ if (block_classes != 0) {
+ spa_config_enter(zcb->zcb_spa, SCL_CONFIG, FTAG, RW_READER);
+
+ uint64_t vdev = DVA_GET_VDEV(&bp->blk_dva[0]);
+ uint64_t offset = DVA_GET_OFFSET(&bp->blk_dva[0]);
+ vdev_t *vd = vdev_lookup_top(zcb->zcb_spa, vdev);
+ ASSERT(vd != NULL);
+ metaslab_t *ms = vd->vdev_ms[offset >> vd->vdev_ms_shift];
+ ASSERT(ms != NULL);
+ metaslab_group_t *mg = ms->ms_group;
+ ASSERT(mg != NULL);
+ metaslab_class_t *mc = mg->mg_class;
+ ASSERT(mc != NULL);
+
+ spa_config_exit(zcb->zcb_spa, SCL_CONFIG, FTAG);
+
+ int class;
+ if (mc == spa_normal_class(zcb->zcb_spa)) {
+ class = CLASS_NORMAL;
+ } else if (mc == spa_special_class(zcb->zcb_spa)) {
+ class = CLASS_SPECIAL;
+ } else if (mc == spa_dedup_class(zcb->zcb_spa)) {
+ class = CLASS_DEDUP;
+ } else {
+ class = CLASS_OTHER;
+ }
+
+ if (!(block_classes & class)) {
+ goto hist_skipped;
+ }
+ }
+
/*
* The binning histogram bins by powers of two up to
* SPA_MAXBLOCKSIZE rather than creating bins for
* every possible blocksize found in the pool.
*/
- int bin = highbit64(BP_GET_PSIZE(bp)) - 1;
+ int bin;
+
+ /*
+ * Binning strategy: each bin includes blocks up to and including
+ * the given size (excluding blocks that fit into the previous bin).
+ * This way, the "4K" bin includes blocks within the (2K; 4K] range.
+ */
+#define BIN(size) (highbit64((size) - 1))
+
+ switch (block_bin_mode) {
+ case BIN_PSIZE: bin = BIN(BP_GET_PSIZE(bp)); break;
+ case BIN_LSIZE: bin = BIN(BP_GET_LSIZE(bp)); break;
+ case BIN_ASIZE: bin = BIN(BP_GET_ASIZE(bp)); break;
+ case BIN_AUTO: break;
+ default: PANIC("bad block_bin_mode"); abort();
+ }
+
+ if (block_bin_mode == BIN_AUTO)
+ bin = BIN(BP_GET_PSIZE(bp));
zcb->zcb_psize_count[bin]++;
zcb->zcb_psize_len[bin] += BP_GET_PSIZE(bp);
zcb->zcb_psize_total += BP_GET_PSIZE(bp);
- bin = highbit64(BP_GET_LSIZE(bp)) - 1;
+ if (block_bin_mode == BIN_AUTO)
+ bin = BIN(BP_GET_LSIZE(bp));
zcb->zcb_lsize_count[bin]++;
zcb->zcb_lsize_len[bin] += BP_GET_LSIZE(bp);
zcb->zcb_lsize_total += BP_GET_LSIZE(bp);
- bin = highbit64(BP_GET_ASIZE(bp)) - 1;
+ if (block_bin_mode == BIN_AUTO)
+ bin = BIN(BP_GET_ASIZE(bp));
zcb->zcb_asize_count[bin]++;
zcb->zcb_asize_len[bin] += BP_GET_ASIZE(bp);
zcb->zcb_asize_total += BP_GET_ASIZE(bp);
+#undef BIN
+
+hist_skipped:
if (!do_claim)
return;
@@ -9426,7 +9534,11 @@ main(int argc, char **argv)
{"livelist", no_argument, NULL, 'y'},
{"zstd-headers", no_argument, NULL, 'Z'},
{"allocated-map", no_argument, NULL,
- ALLOCATED_OPT},
+ ARG_ALLOCATED},
+ {"bin", required_argument, NULL,
+ ARG_BLOCK_BIN_MODE},
+ {"class", required_argument, NULL,
+ ARG_BLOCK_CLASSES},
{0, 0, 0, 0}
};
@@ -9457,7 +9569,7 @@ main(int argc, char **argv)
case 'u':
case 'y':
case 'Z':
- case ALLOCATED_OPT:
+ case ARG_ALLOCATED:
dump_opt[c]++;
dump_all = 0;
break;
@@ -9540,6 +9652,59 @@ main(int argc, char **argv)
case 'x':
vn_dumpdir = optarg;
break;
+ case ARG_BLOCK_BIN_MODE:
+ if (strcmp(optarg, "lsize") == 0) {
+ block_bin_mode = BIN_LSIZE;
+ } else if (strcmp(optarg, "psize") == 0) {
+ block_bin_mode = BIN_PSIZE;
+ } else if (strcmp(optarg, "asize") == 0) {
+ block_bin_mode = BIN_ASIZE;
+ } else {
+ (void) fprintf(stderr,
+ "--bin=\"%s\" must be one of \"lsize\", "
+ "\"psize\" or \"asize\"\n", optarg);
+ usage();
+ }
+ break;
+
+ case ARG_BLOCK_CLASSES: {
+ char *buf = strdup(optarg), *tok = buf, *next,
+ *save = NULL;
+
+ while ((next = strtok_r(tok, ",", &save)) != NULL) {
+ tok = NULL;
+
+ if (strcmp(next, "normal") == 0) {
+ block_classes |= CLASS_NORMAL;
+ } else if (strcmp(next, "special") == 0) {
+ block_classes |= CLASS_SPECIAL;
+ } else if (strcmp(next, "dedup") == 0) {
+ block_classes |= CLASS_DEDUP;
+ } else if (strcmp(next, "other") == 0) {
+ block_classes |= CLASS_OTHER;
+ } else {
+ (void) fprintf(stderr,
+ "--class=\"%s\" must be a "
+ "comma-separated list of either "
+ "\"normal\", \"special\", "
+ "\"asize\" or \"other\"; "
+ "got \"%s\"\n",
+ optarg, next);
+ usage();
+ }
+ }
+
+ if (block_classes == 0) {
+ (void) fprintf(stderr,
+ "--class= must be a comma-separated "
+ "list of either \"normal\", \"special\", "
+ "\"asize\" or \"other\"; got empty\n");
+ usage();
+ }
+
+ free(buf);
+ break;
+ }
default:
usage();
break;
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c
index 088c0108e911..222b5524669e 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c
@@ -270,14 +270,13 @@ is_spare(nvlist_t *config, const char *path)
* draid* Virtual dRAID spare
*/
static nvlist_t *
-make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
+make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)
{
char path[MAXPATHLEN];
struct stat64 statbuf;
nvlist_t *vdev = NULL;
const char *type = NULL;
boolean_t wholedisk = B_FALSE;
- uint64_t ashift = 0;
int err;
/*
@@ -382,31 +381,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
(uint64_t)wholedisk) == 0);
/*
- * Override defaults if custom properties are provided.
- */
- if (props != NULL) {
- const char *value = NULL;
-
- if (nvlist_lookup_string(props,
- zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0) {
- if (zfs_nicestrtonum(NULL, value, &ashift) != 0) {
- (void) fprintf(stderr,
- gettext("ashift must be a number.\n"));
- return (NULL);
- }
- if (ashift != 0 &&
- (ashift < ASHIFT_MIN || ashift > ASHIFT_MAX)) {
- (void) fprintf(stderr,
- gettext("invalid 'ashift=%" PRIu64 "' "
- "property: only values between %" PRId32 " "
- "and %" PRId32 " are allowed.\n"),
- ashift, ASHIFT_MIN, ASHIFT_MAX);
- return (NULL);
- }
- }
- }
-
- /*
* If the device is known to incorrectly report its physical sector
* size explicitly provide the known correct value.
*/
@@ -1513,6 +1487,29 @@ construct_spec(nvlist_t *props, int argc, char **argv)
const char *type, *fulltype;
boolean_t is_log, is_special, is_dedup, is_spare;
boolean_t seen_logs;
+ uint64_t ashift = 0;
+
+ if (props != NULL) {
+ const char *value = NULL;
+
+ if (nvlist_lookup_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0) {
+ if (zfs_nicestrtonum(NULL, value, &ashift) != 0) {
+ (void) fprintf(stderr,
+ gettext("ashift must be a number.\n"));
+ return (NULL);
+ }
+ if (ashift != 0 &&
+ (ashift < ASHIFT_MIN || ashift > ASHIFT_MAX)) {
+ (void) fprintf(stderr,
+ gettext("invalid 'ashift=%" PRIu64 "' "
+ "property: only values between %" PRId32 " "
+ "and %" PRId32 " are allowed.\n"),
+ ashift, ASHIFT_MIN, ASHIFT_MAX);
+ return (NULL);
+ }
+ }
+ }
top = NULL;
toplevels = 0;
@@ -1618,9 +1615,9 @@ construct_spec(nvlist_t *props, int argc, char **argv)
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
- if ((nv = make_leaf_vdev(props, argv[c],
+ if ((nv = make_leaf_vdev(argv[c],
!(is_log || is_special || is_dedup ||
- is_spare))) == NULL) {
+ is_spare), ashift)) == NULL) {
for (c = 0; c < children - 1; c++)
nvlist_free(child[c]);
free(child);
@@ -1684,6 +1681,10 @@ construct_spec(nvlist_t *props, int argc, char **argv)
ZPOOL_CONFIG_ALLOCATION_BIAS,
VDEV_ALLOC_BIAS_DEDUP) == 0);
}
+ if (ashift > 0) {
+ fnvlist_add_uint64(nv,
+ ZPOOL_CONFIG_ASHIFT, ashift);
+ }
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_NPARITY,
@@ -1711,8 +1712,9 @@ construct_spec(nvlist_t *props, int argc, char **argv)
* We have a device. Pass off to make_leaf_vdev() to
* construct the appropriate nvlist describing the vdev.
*/
- if ((nv = make_leaf_vdev(props, argv[0], !(is_log ||
- is_special || is_dedup || is_spare))) == NULL)
+ if ((nv = make_leaf_vdev(argv[0], !(is_log ||
+ is_special || is_dedup || is_spare),
+ ashift)) == NULL)
goto spec_out;
verify(nvlist_add_uint64(nv,
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
index 93aa4984d734..9ada482be000 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h
@@ -41,6 +41,7 @@
#ifndef _LIBSPL_SYS_UIO_H
#define _LIBSPL_SYS_UIO_H
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include_next <sys/uio.h>
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_status.c b/sys/contrib/openzfs/lib/libzfs/libzfs_status.c
index bdddefb92165..a589ca6896f0 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_status.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_status.c
@@ -98,57 +98,57 @@ static const char *const zfs_msgid_table[] = {
#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
static int
-vdev_missing(vdev_stat_t *vs, uint_t vsc)
+vdev_missing(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- (void) vsc;
+ (void) vsc, (void) arg;
return (vs->vs_state == VDEV_STATE_CANT_OPEN &&
vs->vs_aux == VDEV_AUX_OPEN_FAILED);
}
static int
-vdev_faulted(vdev_stat_t *vs, uint_t vsc)
+vdev_faulted(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- (void) vsc;
+ (void) vsc, (void) arg;
return (vs->vs_state == VDEV_STATE_FAULTED);
}
static int
-vdev_errors(vdev_stat_t *vs, uint_t vsc)
+vdev_errors(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- (void) vsc;
+ (void) vsc, (void) arg;
return (vs->vs_state == VDEV_STATE_DEGRADED ||
vs->vs_read_errors != 0 || vs->vs_write_errors != 0 ||
vs->vs_checksum_errors != 0);
}
static int
-vdev_broken(vdev_stat_t *vs, uint_t vsc)
+vdev_broken(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- (void) vsc;
+ (void) vsc, (void) arg;
return (vs->vs_state == VDEV_STATE_CANT_OPEN);
}
static int
-vdev_offlined(vdev_stat_t *vs, uint_t vsc)
+vdev_offlined(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- (void) vsc;
+ (void) vsc, (void) arg;
return (vs->vs_state == VDEV_STATE_OFFLINE);
}
static int
-vdev_removed(vdev_stat_t *vs, uint_t vsc)
+vdev_removed(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- (void) vsc;
+ (void) vsc, (void) arg;
return (vs->vs_state == VDEV_STATE_REMOVED);
}
static int
-vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)
+vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc, void *arg)
{
- if (getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") != NULL)
- return (0);
+ uint64_t ashift = *(uint64_t *)arg;
return (VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
+ (ashift == 0 || vs->vs_configured_ashift < ashift) &&
vs->vs_configured_ashift < vs->vs_physical_ashift);
}
@@ -156,8 +156,8 @@ vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)
* Detect if any leaf devices that have seen errors or could not be opened.
*/
static boolean_t
-find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
- boolean_t ignore_replacing)
+find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t, void *),
+ void *arg, boolean_t ignore_replacing)
{
nvlist_t **child;
uint_t c, children;
@@ -177,14 +177,16 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,
&children) == 0) {
- for (c = 0; c < children; c++)
- if (find_vdev_problem(child[c], func, ignore_replacing))
+ for (c = 0; c < children; c++) {
+ if (find_vdev_problem(child[c], func, arg,
+ ignore_replacing))
return (B_TRUE);
+ }
} else {
uint_t vsc;
vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
vdev, ZPOOL_CONFIG_VDEV_STATS, &vsc);
- if (func(vs, vsc) != 0)
+ if (func(vs, vsc, arg) != 0)
return (B_TRUE);
}
@@ -193,9 +195,11 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
*/
if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,
&children) == 0) {
- for (c = 0; c < children; c++)
- if (find_vdev_problem(child[c], func, ignore_replacing))
+ for (c = 0; c < children; c++) {
+ if (find_vdev_problem(child[c], func, arg,
+ ignore_replacing))
return (B_TRUE);
+ }
}
return (B_FALSE);
@@ -220,7 +224,7 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
*/
static zpool_status_t
check_status(nvlist_t *config, boolean_t isimport,
- zpool_errata_t *erratap, const char *compat)
+ zpool_errata_t *erratap, const char *compat, uint64_t ashift)
{
pool_scan_stat_t *ps = NULL;
uint_t vsc, psc;
@@ -371,15 +375,15 @@ check_status(nvlist_t *config, boolean_t isimport,
* Bad devices in non-replicated config.
*/
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
+ find_vdev_problem(nvroot, vdev_faulted, NULL, B_TRUE))
return (ZPOOL_STATUS_FAULTED_DEV_NR);
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_missing, B_TRUE))
+ find_vdev_problem(nvroot, vdev_missing, NULL, B_TRUE))
return (ZPOOL_STATUS_MISSING_DEV_NR);
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_broken, B_TRUE))
+ find_vdev_problem(nvroot, vdev_broken, NULL, B_TRUE))
return (ZPOOL_STATUS_CORRUPT_LABEL_NR);
/*
@@ -402,35 +406,37 @@ check_status(nvlist_t *config, boolean_t isimport,
/*
* Missing devices in a replicated config.
*/
- if (find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
+ if (find_vdev_problem(nvroot, vdev_faulted, NULL, B_TRUE))
return (ZPOOL_STATUS_FAULTED_DEV_R);
- if (find_vdev_problem(nvroot, vdev_missing, B_TRUE))
+ if (find_vdev_problem(nvroot, vdev_missing, NULL, B_TRUE))
return (ZPOOL_STATUS_MISSING_DEV_R);
- if (find_vdev_problem(nvroot, vdev_broken, B_TRUE))
+ if (find_vdev_problem(nvroot, vdev_broken, NULL, B_TRUE))
return (ZPOOL_STATUS_CORRUPT_LABEL_R);
/*
* Devices with errors
*/
- if (!isimport && find_vdev_problem(nvroot, vdev_errors, B_TRUE))
+ if (!isimport && find_vdev_problem(nvroot, vdev_errors, NULL, B_TRUE))
return (ZPOOL_STATUS_FAILING_DEV);
/*
* Offlined devices
*/
- if (find_vdev_problem(nvroot, vdev_offlined, B_TRUE))
+ if (find_vdev_problem(nvroot, vdev_offlined, NULL, B_TRUE))
return (ZPOOL_STATUS_OFFLINE_DEV);
/*
* Removed device
*/
- if (find_vdev_problem(nvroot, vdev_removed, B_TRUE))
+ if (find_vdev_problem(nvroot, vdev_removed, NULL, B_TRUE))
return (ZPOOL_STATUS_REMOVED_DEV);
/*
* Suboptimal, but usable, ashift configuration.
*/
- if (find_vdev_problem(nvroot, vdev_non_native_ashift, B_FALSE))
+ if (!isimport &&
+ getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") == NULL &&
+ find_vdev_problem(nvroot, vdev_non_native_ashift, &ashift, B_FALSE))
return (ZPOOL_STATUS_NON_NATIVE_ASHIFT);
/*
@@ -510,8 +516,10 @@ zpool_get_status(zpool_handle_t *zhp, const char **msgid,
ZFS_MAXPROPLEN, NULL, B_FALSE) != 0)
compatibility[0] = '\0';
+ uint64_t ashift = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, NULL);
+
zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE, errata,
- compatibility);
+ compatibility, ashift);
if (msgid != NULL) {
if (ret >= NMSGID)
@@ -526,7 +534,7 @@ zpool_status_t
zpool_import_status(nvlist_t *config, const char **msgid,
zpool_errata_t *errata)
{
- zpool_status_t ret = check_status(config, B_TRUE, errata, NULL);
+ zpool_status_t ret = check_status(config, B_TRUE, errata, NULL, 0);
if (ret >= NMSGID)
*msgid = NULL;
diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c
index 8ed374627264..70eba5099119 100644
--- a/sys/contrib/openzfs/lib/libzpool/kernel.c
+++ b/sys/contrib/openzfs/lib/libzpool/kernel.c
@@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
*/
#include <assert.h>
@@ -645,39 +646,60 @@ __dprintf(boolean_t dprint, const char *file, const char *func,
* cmn_err() and panic()
* =========================================================================
*/
-static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
-static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
-__attribute__((noreturn)) void
-vpanic(const char *fmt, va_list adx)
+static __attribute__((noreturn)) void
+panic_stop_or_abort(void)
{
- (void) fprintf(stderr, "error: ");
- (void) vfprintf(stderr, fmt, adx);
- (void) fprintf(stderr, "\n");
+ const char *stopenv = getenv("LIBZPOOL_PANIC_STOP");
+ if (stopenv != NULL && atoi(stopenv)) {
+ fputs("libzpool: LIBZPOOL_PANIC_STOP is set, sending "
+ "SIGSTOP to process group\n", stderr);
+ fflush(stderr);
+
+ kill(0, SIGSTOP);
+
+ fputs("libzpool: continued after panic stop, "
+ "aborting\n", stderr);
+ }
abort(); /* think of it as a "user-level crash dump" */
}
-__attribute__((noreturn)) void
-panic(const char *fmt, ...)
+static void
+vcmn_msg(int ce, const char *fmt, va_list adx)
{
- va_list adx;
+ switch (ce) {
+ case CE_IGNORE:
+ return;
+ case CE_CONT:
+ break;
+ case CE_NOTE:
+ fputs("libzpool: NOTICE: ", stderr);
+ break;
+ case CE_WARN:
+ fputs("libzpool: WARNING: ", stderr);
+ break;
+ case CE_PANIC:
+ fputs("libzpool: PANIC: ", stderr);
+ break;
+ default:
+ fputs("libzpool: [unknown severity %d]: ", stderr);
+ break;
+ }
- va_start(adx, fmt);
- vpanic(fmt, adx);
- va_end(adx);
+ vfprintf(stderr, fmt, adx);
+ if (ce != CE_CONT)
+ fputc('\n', stderr);
+ fflush(stderr);
}
void
vcmn_err(int ce, const char *fmt, va_list adx)
{
+ vcmn_msg(ce, fmt, adx);
+
if (ce == CE_PANIC)
- vpanic(fmt, adx);
- if (ce != CE_NOTE) { /* suppress noise in userland stress testing */
- (void) fprintf(stderr, "%s", ce_prefix[ce]);
- (void) vfprintf(stderr, fmt, adx);
- (void) fprintf(stderr, "%s", ce_suffix[ce]);
- }
+ panic_stop_or_abort();
}
void
@@ -690,6 +712,25 @@ cmn_err(int ce, const char *fmt, ...)
va_end(adx);
}
+__attribute__((noreturn)) void
+panic(const char *fmt, ...)
+{
+ va_list adx;
+
+ va_start(adx, fmt);
+ vcmn_msg(CE_PANIC, fmt, adx);
+ va_end(adx);
+
+ panic_stop_or_abort();
+}
+
+__attribute__((noreturn)) void
+vpanic(const char *fmt, va_list adx)
+{
+ vcmn_msg(CE_PANIC, fmt, adx);
+ panic_stop_or_abort();
+}
+
/*
* =========================================================================
* misc routines
diff --git a/sys/contrib/openzfs/man/man8/zdb.8 b/sys/contrib/openzfs/man/man8/zdb.8
index c3290ea14769..f51e24fa849c 100644
--- a/sys/contrib/openzfs/man/man8/zdb.8
+++ b/sys/contrib/openzfs/man/man8/zdb.8
@@ -144,6 +144,20 @@ subcommand.
Display statistics regarding the number, size
.Pq logical, physical and allocated
and deduplication of blocks.
+.It Fl -bin Ns = Ns ( Li lsize Ns | Ns Li psize Ns | Ns Li asize )
+When used with
+.Fl bb ,
+sort blocks into all three bins according to the given size (instead of binning
+a block for each size separately).
+.Pp
+For instance, with
+.Fl -bin Ns = Ns Li lsize ,
+a block with lsize of 16K and psize of 4K will be added to the 16K bin
+in all three columns.
+.It Fl -class Ns = Ns ( Li normal Ns | Ns Li special Ns | Ns Li dedup Ns | Ns Li other ) Ns Op , Ns …
+When used with
+.Fl bb ,
+only consider blocks from these allocation classes.
.It Fl B , -backup
Generate a backup stream, similar to
.Nm zfs Cm send ,
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
index 4de48e013ec4..d0a9c662e6f0 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
@@ -762,8 +762,7 @@ zfsctl_common_pathconf(struct vop_pathconf_args *ap)
return (0);
case _PC_MIN_HOLE_SIZE:
- *ap->a_retval = (int)SPA_MINBLOCKSIZE;
- return (0);
+ return (EINVAL);
case _PC_ACL_EXTENDED:
*ap->a_retval = 0;
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
index 411225786089..f34a2fd37a77 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
@@ -4116,6 +4116,7 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
{
znode_t *zp;
zfsvfs_t *zfsvfs;
+ uint_t blksize, iosize;
int error;
switch (cmd) {
@@ -4127,8 +4128,20 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
*valp = 64;
return (0);
case _PC_MIN_HOLE_SIZE:
- *valp = (int)SPA_MINBLOCKSIZE;
- return (0);
+ iosize = vp->v_mount->mnt_stat.f_iosize;
+ if (vp->v_type == VREG) {
+ zp = VTOZ(vp);
+ blksize = zp->z_blksz;
+ if (zp->z_size <= blksize)
+ blksize = MAX(blksize, iosize);
+ *valp = (int)blksize;
+ return (0);
+ }
+ if (vp->v_type == VDIR) {
+ *valp = (int)iosize;
+ return (0);
+ }
+ return (EINVAL);
case _PC_ACL_EXTENDED:
#if 0 /* POSIX ACLs are not implemented for ZFS on FreeBSD yet. */
zp = VTOZ(vp);
@@ -4210,8 +4223,20 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind,
zfs_vmobject_wlock(object);
(void) vm_page_grab_pages(object, OFF_TO_IDX(start),
- VM_ALLOC_NORMAL | VM_ALLOC_WAITOK | VM_ALLOC_ZERO,
+ VM_ALLOC_NORMAL | VM_ALLOC_WAITOK,
ma, count);
+ if (!vm_page_all_valid(ma[count - 1])) {
+ /*
+ * Later in this function, we copy DMU data to
+ * invalid pages only. The last page may not be
+ * entirely filled though, if the file does not
+ * end on a page boundary. Therefore, we zero
+ * that last page here to make sure it does not
+ * contain garbage after the end of file.
+ */
+ ASSERT(vm_page_none_valid(ma[count - 1]));
+ vm_page_zero_invalid(ma[count - 1], FALSE);
+ }
zfs_vmobject_wunlock(object);
}
if (blksz == zp->z_blksz)
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
index 0dd2ecd7fd8d..3ddbfcb97184 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
@@ -183,6 +183,7 @@ static struct filterops zvol_filterops_vnode = {
.f_isfd = 1,
.f_detach = zvol_filter_detach,
.f_event = zvol_filter_vnode,
+ .f_copy = knote_triv_copy,
};
extern uint_t zfs_geom_probe_vdev_key;
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
index 967a018640e1..4e66bee7744d 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -337,16 +337,14 @@ zvol_discard(zv_request_t *zvr)
}
/*
- * Align the request to volume block boundaries when a secure erase is
- * not required. This will prevent dnode_free_range() from zeroing out
- * the unaligned parts which is slow (read-modify-write) and useless
- * since we are not freeing any space by doing so.
+ * Align the request to volume block boundaries. This will prevent
+ * dnode_free_range() from zeroing out the unaligned parts which is
+ * slow (read-modify-write) and useless since we are not freeing any
+ * space by doing so.
*/
- if (!io_is_secure_erase(bio, rq)) {
- start = P2ROUNDUP(start, zv->zv_volblocksize);
- end = P2ALIGN_TYPED(end, zv->zv_volblocksize, uint64_t);
- size = end - start;
- }
+ start = P2ROUNDUP(start, zv->zv_volblocksize);
+ end = P2ALIGN_TYPED(end, zv->zv_volblocksize, uint64_t);
+ size = end - start;
if (start >= end)
goto unlock;
@@ -467,6 +465,24 @@ zvol_read_task(void *arg)
zv_request_task_free(task);
}
+/*
+ * Note:
+ *
+ * The kernel uses different enum names for the IO opcode, depending on the
+ * kernel version ('req_opf', 'req_op'). To sidestep this, use macros rather
+ * than inline functions for these checks.
+ */
+/* Should this IO go down the zvol write path? */
+#define ZVOL_OP_IS_WRITE(op) \
+ (op == REQ_OP_WRITE || \
+ op == REQ_OP_FLUSH || \
+ op == REQ_OP_DISCARD)
+
+/* Is this IO type supported by zvols? */
+#define ZVOL_OP_IS_SUPPORTED(op) (op == REQ_OP_READ || ZVOL_OP_IS_WRITE(op))
+
+/* Get the IO opcode */
+#define ZVOL_OP(bio, rq) (bio != NULL ? bio_op(bio) : req_op(rq))
/*
* Process a BIO or request
@@ -486,27 +502,32 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
uint64_t size = io_size(bio, rq);
int rw;
- if (rq != NULL) {
- /*
- * Flush & trim requests go down the zvol_write codepath. Or
- * more specifically:
- *
- * If request is a write, or if it's op_is_sync() and not a
- * read, or if it's a flush, or if it's a discard, then send the
- * request down the write path.
- */
- if (op_is_write(rq->cmd_flags) ||
- (op_is_sync(rq->cmd_flags) && req_op(rq) != REQ_OP_READ) ||
- req_op(rq) == REQ_OP_FLUSH ||
- op_is_discard(rq->cmd_flags)) {
- rw = WRITE;
- } else {
- rw = READ;
- }
+ if (unlikely(!ZVOL_OP_IS_SUPPORTED(ZVOL_OP(bio, rq)))) {
+ zfs_dbgmsg("Unsupported zvol %s, op=%d, flags=0x%x",
+ rq != NULL ? "request" : "BIO",
+ ZVOL_OP(bio, rq),
+ rq != NULL ? rq->cmd_flags : bio->bi_opf);
+ ASSERT(ZVOL_OP_IS_SUPPORTED(ZVOL_OP(bio, rq)));
+ zvol_end_io(bio, rq, SET_ERROR(ENOTSUPP));
+ goto out;
+ }
+
+ if (ZVOL_OP_IS_WRITE(ZVOL_OP(bio, rq))) {
+ rw = WRITE;
} else {
- rw = bio_data_dir(bio);
+ rw = READ;
}
+ /*
+ * Sanity check
+ *
+ * If we're a BIO, check our rw matches the kernel's
+ * bio_data_dir(bio) rw. We need to check because we support fewer
+ * IO operations, and want to verify that what we think are reads and
+ * writes from those operations match what the kernel thinks.
+ */
+ ASSERT(rq != NULL || rw == bio_data_dir(bio));
+
if (unlikely(zv->zv_flags & ZVOL_REMOVING)) {
zvol_end_io(bio, rq, SET_ERROR(ENXIO));
goto out;
@@ -610,7 +631,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
* interfaces lack this functionality (they block waiting for
* the i/o to complete).
*/
- if (io_is_discard(bio, rq) || io_is_secure_erase(bio, rq)) {
+ if (io_is_discard(bio, rq)) {
if (force_sync) {
zvol_discard(&zvr);
} else {
diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c
index b677f90280d7..dbb5e942e2e6 100644
--- a/sys/contrib/openzfs/module/zfs/arc.c
+++ b/sys/contrib/openzfs/module/zfs/arc.c
@@ -1157,7 +1157,7 @@ buf_fini(void)
#if defined(_KERNEL)
/*
* Large allocations which do not require contiguous pages
- * should be using vmem_free() in the linux kernel\
+ * should be using vmem_free() in the linux kernel.
*/
vmem_free(buf_hash_table.ht_table,
(buf_hash_table.ht_mask + 1) * sizeof (void *));
@@ -4651,10 +4651,10 @@ arc_flush_task(void *arg)
arc_flush_impl(spa_guid, B_FALSE);
arc_async_flush_remove(spa_guid, af->af_cache_level);
- uint64_t elaspsed = NSEC2MSEC(gethrtime() - start_time);
- if (elaspsed > 0) {
+ uint64_t elapsed = NSEC2MSEC(gethrtime() - start_time);
+ if (elapsed > 0) {
zfs_dbgmsg("spa %llu arc flushed in %llu ms",
- (u_longlong_t)spa_guid, (u_longlong_t)elaspsed);
+ (u_longlong_t)spa_guid, (u_longlong_t)elapsed);
}
}
@@ -9152,7 +9152,7 @@ top:
if (dev->l2ad_first) {
/*
* This is the first sweep through the device. There is
- * nothing to evict. We have already trimmmed the
+ * nothing to evict. We have already trimmed the
* whole device.
*/
goto out;
@@ -10086,12 +10086,12 @@ l2arc_device_teardown(void *arg)
kmem_free(remdev->l2ad_dev_hdr, remdev->l2ad_dev_hdr_asize);
vmem_free(remdev, sizeof (l2arc_dev_t));
- uint64_t elaspsed = NSEC2MSEC(gethrtime() - start_time);
- if (elaspsed > 0) {
+ uint64_t elapsed = NSEC2MSEC(gethrtime() - start_time);
+ if (elapsed > 0) {
zfs_dbgmsg("spa %llu, vdev %llu removed in %llu ms",
(u_longlong_t)rva->rva_spa_gid,
(u_longlong_t)rva->rva_vdev_gid,
- (u_longlong_t)elaspsed);
+ (u_longlong_t)elapsed);
}
if (rva->rva_async)
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_seek.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_seek.c
index 45ba17e36c35..f46980cad111 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_seek.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_seek.c
@@ -47,25 +47,34 @@
#endif
static void
+seek_expect(int fd, off_t offset, int whence, off_t expect_offset)
+{
+ errno = 0;
+ off_t seek_offset = lseek(fd, offset, whence);
+ if (seek_offset == expect_offset)
+ return;
+
+ int err = errno;
+ fprintf(stderr, "lseek(fd, %ld, SEEK_%s) = %ld (expected %ld)",
+ offset, (whence == SEEK_DATA ? "DATA" : "HOLE"),
+ seek_offset, expect_offset);
+ if (err != 0)
+ fprintf(stderr, " (errno %d [%s])\n", err, strerror(err));
+ else
+ fputc('\n', stderr);
+ exit(2);
+}
+
+static inline void
seek_data(int fd, off_t offset, off_t expected)
{
- off_t data_offset = lseek(fd, offset, SEEK_DATA);
- if (data_offset != expected) {
- fprintf(stderr, "lseek(fd, %d, SEEK_DATA) = %d (expected %d)\n",
- (int)offset, (int)data_offset, (int)expected);
- exit(2);
- }
+ seek_expect(fd, offset, SEEK_DATA, expected);
}
-static void
+static inline void
seek_hole(int fd, off_t offset, off_t expected)
{
- off_t hole_offset = lseek(fd, offset, SEEK_HOLE);
- if (hole_offset != expected) {
- fprintf(stderr, "lseek(fd, %d, SEEK_HOLE) = %d (expected %d)\n",
- (int)offset, (int)hole_offset, (int)expected);
- exit(2);
- }
+ seek_expect(fd, offset, SEEK_HOLE, expected);
}
int
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos.ksh
index 2bd9f616170b..1a9774331ba1 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos.ksh
@@ -47,6 +47,8 @@ function cleanup
# bring back removed disk online for further tests
insert_disk $REMOVED_DISK $scsi_host
poolexists $TESTPOOL && destroy_pool $TESTPOOL
+ # Since the disk was offline during destroy, remove the label
+ zpool labelclear $DISK2 -f
}
log_assert "Testing zpool reopen with pool name as argument"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/zvol/zvol_misc/zvol_misc_trim.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/zvol/zvol_misc/zvol_misc_trim.ksh
index bb697b76a9f3..9de308c4a11a 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/zvol/zvol_misc/zvol_misc_trim.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/zvol/zvol_misc/zvol_misc_trim.ksh
@@ -41,6 +41,7 @@
# 5. TRIM the first 1MB and last 2MB of the 5MB block of data.
# 6. Observe 2MB of used space on the zvol
# 7. Verify the trimmed regions are zero'd on the zvol
+# 8. Verify Secure Erase does not work on zvols (Linux only)
verify_runnable "global"
@@ -56,6 +57,7 @@ if is_linux ; then
else
trimcmd='blkdiscard'
fi
+ secure_trimcmd="$trimcmd --secure"
else
# By default, FreeBSD 'trim' always does a dry-run. '-f' makes
# it perform the actual operation.
@@ -114,6 +116,11 @@ function do_test {
log_must diff $datafile1 $datafile2
log_must rm $datafile1 $datafile2
+
+ # Secure erase should not work (Linux check only).
+ if [ -n "$secure_trimcmd" ] ; then
+ log_mustnot $secure_trimcmd $zvolpath
+ fi
}
log_assert "Verify that a ZFS volume can be TRIMed"
diff --git a/sys/dev/aac/aac_linux.c b/sys/dev/aac/aac_linux.c
index 609315f50939..65008c562342 100644
--- a/sys/dev/aac/aac_linux.c
+++ b/sys/dev/aac/aac_linux.c
@@ -52,15 +52,7 @@
#define AAC_LINUX_IOCTL_MIN 0x0000
#define AAC_LINUX_IOCTL_MAX 0x21ff
-static linux_ioctl_function_t aac_linux_ioctl;
-static struct linux_ioctl_handler aac_linux_handler = {aac_linux_ioctl,
- AAC_LINUX_IOCTL_MIN,
- AAC_LINUX_IOCTL_MAX};
-
-SYSINIT (aac_linux_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &aac_linux_handler);
-SYSUNINIT(aac_linux_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &aac_linux_handler);
+LINUX_IOCTL_SET(aac, AAC_LINUX_IOCTL_MIN, AAC_LINUX_IOCTL_MAX);
static int
aac_linux_modevent(module_t mod, int type, void *data)
diff --git a/sys/dev/aacraid/aacraid_linux.c b/sys/dev/aacraid/aacraid_linux.c
index 267dd84c65d5..6b6259ed7059 100644
--- a/sys/dev/aacraid/aacraid_linux.c
+++ b/sys/dev/aacraid/aacraid_linux.c
@@ -54,15 +54,7 @@
#define AAC_LINUX_IOCTL_MIN 0x0000
#define AAC_LINUX_IOCTL_MAX 0x21ff
-static linux_ioctl_function_t aacraid_linux_ioctl;
-static struct linux_ioctl_handler aacraid_linux_handler = {aacraid_linux_ioctl,
- AAC_LINUX_IOCTL_MIN,
- AAC_LINUX_IOCTL_MAX};
-
-SYSINIT (aacraid_linux_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &aacraid_linux_handler);
-SYSUNINIT(aacraid_linux_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &aacraid_linux_handler);
+LINUX_IOCTL_SET(aacraid, AAC_LINUX_IOCTL_MIN, AAC_LINUX_IOCTL_MAX);
static int
aacraid_linux_modevent(module_t mod, int type, void *data)
diff --git a/sys/dev/ahci/ahciem.c b/sys/dev/ahci/ahciem.c
index c9e6c35f4233..012796aa5d6f 100644
--- a/sys/dev/ahci/ahciem.c
+++ b/sys/dev/ahci/ahciem.c
@@ -479,7 +479,7 @@ ahci_em_emulate_ses_on_led(device_t dev, union ccb *ccb)
else
ads->common.bytes[0] |= SES_OBJSTAT_NOTINSTALLED;
if (ch->disablephy)
- ads->common.bytes[3] |= SESCTL_DEVOFF;
+ ads->bytes[2] |= SESCTL_DEVOFF;
ahci_putch(ch);
}
ccb->ccb_h.status = CAM_REQ_CMP;
diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index 8563b5f93aa2..137758b104d3 100644
--- a/sys/dev/atkbdc/psm.c
+++ b/sys/dev/atkbdc/psm.c
@@ -5287,6 +5287,7 @@ static const struct filterops psmfiltops = {
.f_isfd = 1,
.f_detach = psmfilter_detach,
.f_event = psmfilter,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/dev/cyapa/cyapa.c b/sys/dev/cyapa/cyapa.c
index ed755f992949..464b03c0ab64 100644
--- a/sys/dev/cyapa/cyapa.c
+++ b/sys/dev/cyapa/cyapa.c
@@ -1121,7 +1121,8 @@ static int cyapafilt(struct knote *, long);
static const struct filterops cyapa_filtops = {
.f_isfd = 1,
.f_detach = cyapafiltdetach,
- .f_event = cyapafilt
+ .f_event = cyapafilt,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/dev/evdev/cdev.c b/sys/dev/evdev/cdev.c
index 9fe1299a0937..dd4115cdfc71 100644
--- a/sys/dev/evdev/cdev.c
+++ b/sys/dev/evdev/cdev.c
@@ -96,6 +96,7 @@ static const struct filterops evdev_cdev_filterops = {
.f_attach = NULL,
.f_detach = evdev_kqdetach,
.f_event = evdev_kqread,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/dev/evdev/uinput.c b/sys/dev/evdev/uinput.c
index 9ac9fee8a157..76a530479c02 100644
--- a/sys/dev/evdev/uinput.c
+++ b/sys/dev/evdev/uinput.c
@@ -104,6 +104,7 @@ static const struct filterops uinput_filterops = {
.f_attach = NULL,
.f_detach = uinput_kqdetach,
.f_event = uinput_kqread,
+ .f_copy = knote_triv_copy,
};
struct uinput_cdev_state
diff --git a/sys/dev/gpio/gpioc.c b/sys/dev/gpio/gpioc.c
index 6c6f79227166..517f7752daad 100644
--- a/sys/dev/gpio/gpioc.c
+++ b/sys/dev/gpio/gpioc.c
@@ -158,7 +158,8 @@ static const struct filterops gpioc_read_filterops = {
.f_attach = NULL,
.f_detach = gpioc_kqdetach,
.f_event = gpioc_kqread,
- .f_touch = NULL
+ .f_touch = NULL,
+ .f_copy = knote_triv_copy,
};
static struct gpioc_pin_event *
diff --git a/sys/dev/hid/hidraw.c b/sys/dev/hid/hidraw.c
index 4855843cd265..5b5e9b58f8bd 100644
--- a/sys/dev/hid/hidraw.c
+++ b/sys/dev/hid/hidraw.c
@@ -182,6 +182,7 @@ static const struct filterops hidraw_filterops_read = {
.f_isfd = 1,
.f_detach = hidraw_kqdetach,
.f_event = hidraw_kqread,
+ .f_copy = knote_triv_copy,
};
static void
diff --git a/sys/dev/hid/u2f.c b/sys/dev/hid/u2f.c
index 08f1a5ceedba..e1f696d72f01 100644
--- a/sys/dev/hid/u2f.c
+++ b/sys/dev/hid/u2f.c
@@ -132,6 +132,7 @@ static struct filterops u2f_filterops_read = {
.f_isfd = 1,
.f_detach = u2f_kqdetach,
.f_event = u2f_kqread,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c
index 668ccf056463..82f73d469585 100644
--- a/sys/dev/iommu/busdma_iommu.c
+++ b/sys/dev/iommu/busdma_iommu.c
@@ -295,7 +295,6 @@ iommu_instantiate_ctx(struct iommu_unit *unit, device_t dev, bool rmrr)
} else {
iommu_free_ctx_locked(unit, ctx);
}
- ctx = NULL;
}
return (ctx);
}
@@ -303,6 +302,7 @@ iommu_instantiate_ctx(struct iommu_unit *unit, device_t dev, bool rmrr)
struct iommu_ctx *
iommu_get_dev_ctx(device_t dev)
{
+ struct iommu_ctx *ctx;
struct iommu_unit *unit;
unit = iommu_find(dev, bootverbose);
@@ -313,7 +313,10 @@ iommu_get_dev_ctx(device_t dev)
return (NULL);
iommu_unit_pre_instantiate_ctx(unit);
- return (iommu_instantiate_ctx(unit, dev, false));
+ ctx = iommu_instantiate_ctx(unit, dev, false);
+ if (ctx != NULL && (ctx->flags & IOMMU_CTX_DISABLED) != 0)
+ ctx = NULL;
+ return (ctx);
}
bus_dma_tag_t
diff --git a/sys/dev/ipmi/ipmi_linux.c b/sys/dev/ipmi/ipmi_linux.c
index 05eb30a0aa77..58872de12003 100644
--- a/sys/dev/ipmi/ipmi_linux.c
+++ b/sys/dev/ipmi/ipmi_linux.c
@@ -66,15 +66,7 @@
#define L_IPMICTL_SET_MY_LUN_CMD _IOW(IPMI_IOC_MAGIC, 19, unsigned int)
#define L_IPMICTL_GET_MY_LUN_CMD _IOW(IPMI_IOC_MAGIC, 20, unsigned int)
-static linux_ioctl_function_t ipmi_linux_ioctl;
-static struct linux_ioctl_handler ipmi_linux_handler = {ipmi_linux_ioctl,
- IPMI_LINUX_IOCTL_MIN,
- IPMI_LINUX_IOCTL_MAX};
-
-SYSINIT (ipmi_linux_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &ipmi_linux_handler);
-SYSUNINIT(ipmi_linux_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &ipmi_linux_handler);
+LINUX_IOCTL_SET(ipmi, IPMI_LINUX_IOCTL_MIN, IPMI_LINUX_IOCTL_MAX);
static int
ipmi_linux_modevent(module_t mod, int type, void *data)
diff --git a/sys/dev/mfi/mfi_linux.c b/sys/dev/mfi/mfi_linux.c
index 8ed8baa3858a..9541ff37336a 100644
--- a/sys/dev/mfi/mfi_linux.c
+++ b/sys/dev/mfi/mfi_linux.c
@@ -53,15 +53,7 @@
#define MFI_LINUX_IOCTL_MIN 0x4d00
#define MFI_LINUX_IOCTL_MAX 0x4d04
-static linux_ioctl_function_t mfi_linux_ioctl;
-static struct linux_ioctl_handler mfi_linux_handler = {mfi_linux_ioctl,
- MFI_LINUX_IOCTL_MIN,
- MFI_LINUX_IOCTL_MAX};
-
-SYSINIT (mfi_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &mfi_linux_handler);
-SYSUNINIT(mfi_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &mfi_linux_handler);
+LINUX_IOCTL_SET(mfi, MFI_LINUX_IOCTL_MIN, MFI_LINUX_IOCTL_MAX);
static struct linux_device_handler mfi_device_handler =
{ "mfi", "megaraid_sas", "mfi0", "megaraid_sas_ioctl_node", -1, 0, 1};
diff --git a/sys/dev/mrsas/mrsas_linux.c b/sys/dev/mrsas/mrsas_linux.c
index d7d48740a204..b06788fffc82 100644
--- a/sys/dev/mrsas/mrsas_linux.c
+++ b/sys/dev/mrsas/mrsas_linux.c
@@ -67,15 +67,7 @@
#define MRSAS_LINUX_IOCTL_MIN 0x4d00
#define MRSAS_LINUX_IOCTL_MAX 0x4d01
-static linux_ioctl_function_t mrsas_linux_ioctl;
-static struct linux_ioctl_handler mrsas_linux_handler = {mrsas_linux_ioctl,
- MRSAS_LINUX_IOCTL_MIN,
-MRSAS_LINUX_IOCTL_MAX};
-
-SYSINIT(mrsas_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_register_handler, &mrsas_linux_handler);
-SYSUNINIT(mrsas_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
- linux_ioctl_unregister_handler, &mrsas_linux_handler);
+LINUX_IOCTL_SET(mrsas, MRSAS_LINUX_IOCTL_MIN, MRSAS_LINUX_IOCTL_MAX);
static struct linux_device_handler mrsas_device_handler =
{"mrsas", "megaraid_sas", "mrsas0", "megaraid_sas_ioctl_node", -1, 0, 1};
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index ac267a66d669..9fb4370129f3 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -1407,19 +1407,34 @@ netmap_knwrite(struct knote *kn, long hint)
return netmap_knrw(kn, hint, POLLOUT);
}
+static int
+netmap_kncopy(struct knote *kn, struct proc *p1)
+{
+ struct netmap_priv_d *priv;
+ struct nm_selinfo *si;
+
+ priv = kn->kn_hook;
+ si = priv->np_si[kn->kn_filter == EVFILT_WRITE ? NR_TX : NR_RX];
+ NMG_LOCK();
+ si->kqueue_users++;
+ NMG_UNLOCK();
+ return (0);
+}
+
static const struct filterops netmap_rfiltops = {
.f_isfd = 1,
.f_detach = netmap_knrdetach,
.f_event = netmap_knread,
+ .f_copy = netmap_kncopy,
};
static const struct filterops netmap_wfiltops = {
.f_isfd = 1,
.f_detach = netmap_knwdetach,
.f_event = netmap_knwrite,
+ .f_copy = netmap_kncopy,
};
-
/*
* This is called when a thread invokes kevent() to record
* a change in the configuration of the kqueue().
diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c
index 8525eb9543c3..b5725de30bef 100644
--- a/sys/dev/null/null.c
+++ b/sys/dev/null/null.c
@@ -61,12 +61,14 @@ static int zero_ev(struct knote *kn, long hint);
static const struct filterops one_fop = {
.f_isfd = 1,
- .f_event = one_ev
+ .f_event = one_ev,
+ .f_copy = knote_triv_copy,
};
static const struct filterops zero_fop = {
.f_isfd = 1,
- .f_event = zero_ev
+ .f_event = zero_ev,
+ .f_copy = knote_triv_copy,
};
static struct cdevsw full_cdevsw = {
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index 3a1894bf754d..f212759a5500 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -33,6 +33,7 @@
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/conf.h>
+#include <sys/disk.h>
#include <sys/ioccom.h>
#include <sys/proc.h>
#include <sys/smp.h>
@@ -1254,6 +1255,24 @@ nvme_ctrlr_poll(struct nvme_controller *ctrlr)
}
/*
+ * Copy the NVME device's serial number to the provided buffer, which must be
+ * at least DISK_IDENT_SIZE bytes large.
+ */
+void
+nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn)
+{
+ _Static_assert(NVME_SERIAL_NUMBER_LENGTH < DISK_IDENT_SIZE,
+ "NVME serial number too big for disk ident");
+
+ memmove(sn, ctrlr->cdata.sn, NVME_SERIAL_NUMBER_LENGTH);
+ sn[NVME_SERIAL_NUMBER_LENGTH] = '\0';
+ for (int i = 0; sn[i] != '\0'; i++) {
+ if (sn[i] < 0x20 || sn[i] >= 0x80)
+ sn[i] = ' ';
+ }
+}
+
+/*
* Poll the single-vector interrupt case: num_io_queues will be 1 and
* there's only a single vector. While we're polling, we mask further
* interrupts in the controller.
@@ -1495,6 +1514,11 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,
case NVME_GET_CONTROLLER_DATA:
memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata));
break;
+ case DIOCGIDENT: {
+ uint8_t *sn = arg;
+ nvme_ctrlr_get_ident(ctrlr, sn);
+ break;
+ }
/* Linux Compatible (see nvme_linux.h) */
case NVME_IOCTL_ID:
td->td_retval[0] = 0xfffffffful;
diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index e84d2066930e..a759181a8c16 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -88,6 +88,11 @@ nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,
gnsid->nsid = ns->id;
break;
}
+ case DIOCGIDENT: {
+ uint8_t *sn = arg;
+ nvme_ctrlr_get_ident(ctrlr, sn);
+ break;
+ }
case DIOCGMEDIASIZE:
*(off_t *)arg = (off_t)nvme_ns_get_size(ns);
break;
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
index 52e9fcbbebcd..04a47d799350 100644
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -563,6 +563,7 @@ void nvme_notify_new_controller(struct nvme_controller *ctrlr);
void nvme_notify_ns(struct nvme_controller *ctrlr, int nsid);
void nvme_ctrlr_shared_handler(void *arg);
+void nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn);
void nvme_ctrlr_poll(struct nvme_controller *ctrlr);
int nvme_ctrlr_suspend(struct nvme_controller *ctrlr);
diff --git a/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c
index 67e1d4ad2cab..c5b745bb78fb 100644
--- a/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c
+++ b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c
@@ -89,6 +89,7 @@ static struct filterops adf_state_read_filterops = {
.f_attach = NULL,
.f_detach = adf_state_kqread_detach,
.f_event = adf_state_kqread_event,
+ .f_copy = knote_triv_copy,
};
static struct cdev *adf_processes_dev;
diff --git a/sys/dev/random/fenestrasX/fx_pool.c b/sys/dev/random/fenestrasX/fx_pool.c
index f4ad1e295d54..ec59b97a2070 100644
--- a/sys/dev/random/fenestrasX/fx_pool.c
+++ b/sys/dev/random/fenestrasX/fx_pool.c
@@ -167,9 +167,6 @@ static const struct fxrng_ent_char {
[RANDOM_RANDOMDEV] = {
.entc_cls = &fxrng_lo_push,
},
- [RANDOM_PURE_OCTEON] = {
- .entc_cls = &fxrng_hi_push, /* Could be made pull. */
- },
[RANDOM_PURE_SAFE] = {
.entc_cls = &fxrng_hi_push,
},
diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c
index fa1e4831f1b9..3eb0f261e6dc 100644
--- a/sys/dev/random/ivy.c
+++ b/sys/dev/random/ivy.c
@@ -1,6 +1,6 @@
/*-
+ * Copyright (c) 2013, 2025, David E. O'Brien <deo@NUXI.org>
* Copyright (c) 2013 The FreeBSD Foundation
- * Copyright (c) 2013 David E. O'Brien <obrien@NUXI.org>
* Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
* All rights reserved.
*
@@ -48,7 +48,6 @@
#define RETRY_COUNT 10
-static bool has_rdrand, has_rdseed;
static u_int random_ivy_read(void *, u_int);
static const struct random_source random_ivy = {
@@ -57,13 +56,7 @@ static const struct random_source random_ivy = {
.rs_read = random_ivy_read
};
-SYSCTL_NODE(_kern_random, OID_AUTO, rdrand, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
- "rdrand (ivy) entropy source");
static bool acquire_independent_seed_samples = false;
-SYSCTL_BOOL(_kern_random_rdrand, OID_AUTO, rdrand_independent_seed,
- CTLFLAG_RWTUN, &acquire_independent_seed_samples, 0,
- "If non-zero, use more expensive and slow, but safer, seeded samples "
- "where RDSEED is not present.");
static bool
x86_rdrand_store(u_long *buf)
@@ -99,45 +92,6 @@ x86_rdrand_store(u_long *buf)
return (true);
}
-static bool
-x86_rdseed_store(u_long *buf)
-{
- u_long rndval;
- int retry;
-
- retry = RETRY_COUNT;
- __asm __volatile(
- "1:\n\t"
- "rdseed %1\n\t" /* read randomness into rndval */
- "jc 2f\n\t" /* CF is set on success, exit retry loop */
- "dec %0\n\t" /* otherwise, retry-- */
- "jne 1b\n\t" /* and loop if retries are not exhausted */
- "2:"
- : "+r" (retry), "=r" (rndval) : : "cc");
- *buf = rndval;
- return (retry != 0);
-}
-
-static bool
-x86_unimpl_store(u_long *buf __unused)
-{
-
- panic("%s called", __func__);
-}
-
-DEFINE_IFUNC(static, bool, x86_rng_store, (u_long *buf))
-{
- has_rdrand = (cpu_feature2 & CPUID2_RDRAND);
- has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
-
- if (has_rdseed)
- return (x86_rdseed_store);
- else if (has_rdrand)
- return (x86_rdrand_store);
- else
- return (x86_unimpl_store);
-}
-
/* It is required that buf length is a multiple of sizeof(u_long). */
static u_int
random_ivy_read(void *buf, u_int c)
@@ -148,7 +102,7 @@ random_ivy_read(void *buf, u_int c)
KASSERT(c % sizeof(*b) == 0, ("partial read %d", c));
b = buf;
for (count = c; count > 0; count -= sizeof(*b)) {
- if (!x86_rng_store(&rndval))
+ if (!x86_rdrand_store(&rndval))
break;
*b++ = rndval;
}
@@ -158,18 +112,33 @@ random_ivy_read(void *buf, u_int c)
static int
rdrand_modevent(module_t mod, int type, void *unused)
{
+ struct sysctl_ctx_list ctx;
+ struct sysctl_oid *o;
+ bool has_rdrand, has_rdseed;
int error = 0;
+ has_rdrand = (cpu_feature2 & CPUID2_RDRAND);
+ has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
+
switch (type) {
case MOD_LOAD:
- if (has_rdrand || has_rdseed) {
+ if (has_rdrand && !has_rdseed) {
+ sysctl_ctx_init(&ctx);
+ o = SYSCTL_ADD_NODE(&ctx, SYSCTL_STATIC_CHILDREN(_kern_random),
+ OID_AUTO, "rdrand", CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ "rdrand (ivy) entropy source");
+ SYSCTL_ADD_BOOL(&ctx, SYSCTL_CHILDREN(o), OID_AUTO,
+ "rdrand_independent_seed", CTLFLAG_RDTUN,
+ &acquire_independent_seed_samples, 0,
+ "If non-zero, use more expensive and slow, but safer, seeded samples "
+ "where RDSEED is not present.");
random_source_register(&random_ivy);
printf("random: fast provider: \"%s\"\n", random_ivy.rs_ident);
}
break;
case MOD_UNLOAD:
- if (has_rdrand || has_rdseed)
+ if (has_rdrand && !has_rdseed)
random_source_deregister(&random_ivy);
break;
diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
index 2d7af254c52c..e38fd38c310b 100644
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -661,11 +661,11 @@ static const char *random_source_descr[ENTROPYSOURCE] = {
[RANDOM_UMA] = "UMA",
[RANDOM_CALLOUT] = "CALLOUT",
[RANDOM_RANDOMDEV] = "RANDOMDEV", /* ENVIRONMENTAL_END */
- [RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */
- [RANDOM_PURE_SAFE] = "PURE_SAFE",
+ [RANDOM_PURE_SAFE] = "PURE_SAFE", /* PURE_START */
[RANDOM_PURE_GLXSB] = "PURE_GLXSB",
[RANDOM_PURE_HIFN] = "PURE_HIFN",
[RANDOM_PURE_RDRAND] = "PURE_RDRAND",
+ [RANDOM_PURE_RDSEED] = "PURE_RDSEED",
[RANDOM_PURE_NEHEMIAH] = "PURE_NEHEMIAH",
[RANDOM_PURE_RNDTEST] = "PURE_RNDTEST",
[RANDOM_PURE_VIRTIO] = "PURE_VIRTIO",
diff --git a/sys/dev/random/rdseed.c b/sys/dev/random/rdseed.c
new file mode 100644
index 000000000000..af084aab4ed9
--- /dev/null
+++ b/sys/dev/random/rdseed.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2013, 2025, David E. O'Brien <deo@NUXI.org>
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/random.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <machine/md_var.h>
+#include <machine/specialreg.h>
+#include <x86/ifunc.h>
+
+#include <dev/random/randomdev.h>
+
+#define RETRY_COUNT 10
+
+static u_int random_rdseed_read(void *, u_int);
+
+static struct random_source random_rdseed = {
+ .rs_ident = "Intel Secure Key Seed",
+ .rs_source = RANDOM_PURE_RDSEED,
+ .rs_read = random_rdseed_read
+};
+
+SYSCTL_NODE(_kern_random, OID_AUTO, rdseed, CTLFLAG_RW, 0,
+ "rdseed (x86) entropy source");
+/* XXX: kern.random.rdseed.enabled=0 also disables RDRAND */
+static bool enabled = true;
+SYSCTL_BOOL(_kern_random_rdseed, OID_AUTO, enabled, CTLFLAG_RDTUN, &enabled, 0,
+ "If zero, disable the use of RDSEED.");
+
+static bool
+x86_rdseed_store(u_long *buf)
+{
+ u_long rndval;
+ int retry;
+
+ retry = RETRY_COUNT;
+ __asm __volatile(
+ "1:\n\t"
+ "rdseed %1\n\t" /* read randomness into rndval */
+ "jc 2f\n\t" /* CF is set on success, exit retry loop */
+ "dec %0\n\t" /* otherwise, retry-- */
+ "jne 1b\n\t" /* and loop if retries are not exhausted */
+ "2:"
+ : "+r" (retry), "=r" (rndval) : : "cc");
+ *buf = rndval;
+ return (retry != 0);
+}
+
+/* It is required that buf length is a multiple of sizeof(u_long). */
+static u_int
+random_rdseed_read(void *buf, u_int c)
+{
+ u_long *b, rndval;
+ u_int count;
+
+ KASSERT(c % sizeof(*b) == 0, ("partial read %d", c));
+ b = buf;
+ for (count = c; count > 0; count -= sizeof(*b)) {
+ if (!x86_rdseed_store(&rndval))
+ break;
+ *b++ = rndval;
+ }
+ return (c - count);
+}
+
+static int
+rdseed_modevent(module_t mod, int type, void *unused)
+{
+ bool has_rdseed;
+ int error = 0;
+
+ has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
+
+ switch (type) {
+ case MOD_LOAD:
+ if (has_rdseed && enabled) {
+ random_source_register(&random_rdseed);
+ printf("random: fast provider: \"%s\"\n", random_rdseed.rs_ident);
+ }
+ break;
+
+ case MOD_UNLOAD:
+ if (has_rdseed)
+ random_source_deregister(&random_rdseed);
+ break;
+
+ case MOD_SHUTDOWN:
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+
+ }
+
+ return (error);
+}
+
+static moduledata_t rdseed_mod = {
+ "rdseed",
+ rdseed_modevent,
+ 0
+};
+
+DECLARE_MODULE(rdseed, rdseed_mod, SI_SUB_RANDOM, SI_ORDER_FOURTH);
+MODULE_VERSION(rdseed, 1);
+MODULE_DEPEND(rdseed, random_harvestq, 1, 1, 1);
+
+/*
+ * Intel's RDSEED Entropy Assessment Report min-entropy claim is 0.6 Shannons
+ * per bit of data output. Rrefer to the following Entropy Source Validation
+ * (ESV) certificates:
+ *
+ * E#87: Junos OS Physical Entropy Source - Broadwell EP 10-Core Die
+ * Broadwell-EP-10 FCLGA2011 Intel(R) Xeon(R) E5-2620 V4 Processor
+ * https://csrc.nist.gov/projects/cryptographic-module-validation-program/entropy-validations/certificate/87
+ * (URLs below omitted for brevity but follow same format.)
+ *
+ * E#121: Junos OS Physical Entropy Source - Intel Atom C3000 Series
+ * (Denverton) 16 Core Die with FCBGA1310 Package
+ *
+ * E#122: Junos OS Physical Entropy Source - Intel Xeon D-1500 Family
+ * (Broadwell) 8 Core Die with FCBGA1667 Package
+ *
+ * E#123: Junos OS Physical Entropy Source - Intel Xeon D-2100 Series
+ * (Skylake) 18 Core Die with FCBGA2518 Package
+ *
+ * E#141: Junos OS Physical Entropy Source - Intel Xeon D-10 Series
+ * (Ice Lake-D-10) Die with FCBGA2227 Package
+ *
+ * E#169: Junos OS Physical Entropy Source - Intel Xeon AWS-1000 v4 and
+ * E5 v4 (Broadwell EP) 15 Core Die with FCLGA2011 Package
+ */
diff --git a/sys/dev/sound/dummy.c b/sys/dev/sound/dummy.c
index 4df5b112d3f4..1f2d69708eec 100644
--- a/sys/dev/sound/dummy.c
+++ b/sys/dev/sound/dummy.c
@@ -346,6 +346,12 @@ dummy_attach(device_t dev)
return (ENXIO);
mixer_init(dev, &dummy_mixer_class, sc);
+ /*
+ * Create an alias so that tests do not need to guess which one is the
+ * dummy device if there are more devices present in the system.
+ */
+ make_dev_alias(sc->info.dsp_dev, "dsp.dummy");
+
return (0);
}
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 80028063bb0d..8a325c538b9b 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -170,6 +170,7 @@ static const struct {
{ HDA_NVIDIA_GF119, "NVIDIA GF119", 0, 0 },
{ HDA_NVIDIA_GF110_1, "NVIDIA GF110", 0, HDAC_QUIRK_MSI },
{ HDA_NVIDIA_GF110_2, "NVIDIA GF110", 0, HDAC_QUIRK_MSI },
+ { HDA_ATI_RAVEN, "ATI Raven", 0, 0 },
{ HDA_ATI_SB450, "ATI SB450", 0, 0 },
{ HDA_ATI_SB600, "ATI SB600", 0, 0 },
{ HDA_ATI_RS600, "ATI RS600", 0, 0 },
diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h
index c11e6b2d6810..8fb54108a833 100644
--- a/sys/dev/sound/pci/hda/hdac.h
+++ b/sys/dev/sound/pci/hda/hdac.h
@@ -154,6 +154,7 @@
/* ATI */
#define ATI_VENDORID 0x1002
+#define HDA_ATI_RAVEN HDA_MODEL_CONSTRUCT(ATI, 0x15de)
#define HDA_ATI_SB450 HDA_MODEL_CONSTRUCT(ATI, 0x437b)
#define HDA_ATI_SB600 HDA_MODEL_CONSTRUCT(ATI, 0x4383)
#define HDA_ATI_RS600 HDA_MODEL_CONSTRUCT(ATI, 0x793b)
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index fe5576baf017..27d5b740b90b 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -83,15 +83,15 @@ static d_mmap_t dsp_mmap;
static d_mmap_single_t dsp_mmap_single;
struct cdevsw dsp_cdevsw = {
- .d_version = D_VERSION,
- .d_open = dsp_open,
- .d_read = dsp_read,
- .d_write = dsp_write,
- .d_ioctl = dsp_ioctl,
- .d_poll = dsp_poll,
- .d_mmap = dsp_mmap,
- .d_mmap_single = dsp_mmap_single,
- .d_name = "dsp",
+ .d_version = D_VERSION,
+ .d_open = dsp_open,
+ .d_read = dsp_read,
+ .d_write = dsp_write,
+ .d_ioctl = dsp_ioctl,
+ .d_poll = dsp_poll,
+ .d_mmap = dsp_mmap,
+ .d_mmap_single = dsp_mmap_single,
+ .d_name = "dsp",
};
static eventhandler_tag dsp_ehtag = NULL;
diff --git a/sys/dev/tdfx/tdfx_linux.c b/sys/dev/tdfx/tdfx_linux.c
index f3410106bad2..777144d21bb6 100644
--- a/sys/dev/tdfx/tdfx_linux.c
+++ b/sys/dev/tdfx/tdfx_linux.c
@@ -42,7 +42,7 @@ LINUX_IOCTL_SET(tdfx, LINUX_IOCTL_TDFX_MIN, LINUX_IOCTL_TDFX_MAX);
* Linux emulation IOCTL for /dev/tdfx
*/
static int
-linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args)
+tdfx_linux_ioctl(struct thread *td, struct linux_ioctl_args* args)
{
cap_rights_t rights;
int error = 0;
diff --git a/sys/dev/tdfx/tdfx_linux.h b/sys/dev/tdfx/tdfx_linux.h
index b87cb41f38fe..9d012c12274b 100644
--- a/sys/dev/tdfx/tdfx_linux.h
+++ b/sys/dev/tdfx/tdfx_linux.h
@@ -35,18 +35,6 @@
#include <machine/../linux/linux_proto.h>
#include <compat/linux/linux_ioctl.h>
-/*
- * This code was donated by Vladimir N. Silynaev to allow for defining
- * ioctls within modules
- */
-#define LINUX_IOCTL_SET(n,low,high) \
-static linux_ioctl_function_t linux_ioctl_##n; \
-static struct linux_ioctl_handler n##_handler = {linux_ioctl_##n, low, high}; \
-SYSINIT(n##register, SI_SUB_KLD, SI_ORDER_MIDDLE,\
-linux_ioctl_register_handler, &n##_handler); \
-SYSUNINIT(n##unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,\
-linux_ioctl_unregister_handler, &n##_handler);
-
/* Values for /dev/3dfx */
/* Query IOCTLs */
#define LINUX_IOCTL_TDFX_QUERY_BOARDS 0x3302
diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index d7298ab89df7..9550002e3b70 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -88,6 +88,7 @@
#define PCI_EHCI_VENDORID_NEC 0x1033
#define PCI_EHCI_VENDORID_OPTI 0x1045
#define PCI_EHCI_VENDORID_PHILIPS 0x1131
+#define PCI_EHCI_VENDORID_REALTEK 0x10ec
#define PCI_EHCI_VENDORID_SIS 0x1039
#define PCI_EHCI_VENDORID_NVIDIA 0x12D2
#define PCI_EHCI_VENDORID_NVIDIA2 0x10DE
@@ -218,6 +219,9 @@ ehci_pci_match(device_t self)
case 0x15621131:
return "Philips ISP156x USB 2.0 controller";
+ case 0x816d10ec:
+ return ("Realtek RTL811x USB 2.0 controller");
+
case 0x70021039:
return "SiS 968 USB 2.0 controller";
@@ -402,6 +406,9 @@ ehci_pci_attach(device_t self)
case PCI_EHCI_VENDORID_PHILIPS:
sprintf(sc->sc_vendor, "Philips");
break;
+ case PCI_EHCI_VENDORID_REALTEK:
+ sprintf(sc->sc_vendor, "Realtek");
+ break;
case PCI_EHCI_VENDORID_SIS:
sprintf(sc->sc_vendor, "SiS");
break;
diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c
index 293b0c72587f..e58d6a674ec0 100644
--- a/sys/dev/usb/usb_dev.c
+++ b/sys/dev/usb/usb_dev.c
@@ -1231,12 +1231,14 @@ static const struct filterops usb_filtops_write = {
.f_isfd = 1,
.f_detach = usb_filter_detach,
.f_event = usb_filter_write,
+ .f_copy = knote_triv_copy,
};
static const struct filterops usb_filtops_read = {
.f_isfd = 1,
.f_detach = usb_filter_detach,
.f_event = usb_filter_read,
+ .f_copy = knote_triv_copy,
};
/* ARGSUSED */
diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
index 4961b21180e1..ebbceb25b69e 100644
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -14,6 +14,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mman.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/sx.h>
@@ -470,6 +471,12 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
if (ioctl == NULL)
return (ENOTTY);
+ if ((ioctl->flags & VMMDEV_IOCTL_PRIV_CHECK_DRIVER) != 0) {
+ error = priv_check(td, PRIV_DRIVER);
+ if (error != 0)
+ return (error);
+ }
+
if ((ioctl->flags & VMMDEV_IOCTL_XLOCK_MEMSEGS) != 0)
vm_xlock_memsegs(sc->vm);
else if ((ioctl->flags & VMMDEV_IOCTL_SLOCK_MEMSEGS) != 0)
@@ -656,10 +663,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
error = EINVAL;
break;
}
- regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV,
- M_WAITOK);
- regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV,
- M_WAITOK);
+ regvals = mallocarray(vmregset->count, sizeof(regvals[0]),
+ M_VMMDEV, M_WAITOK);
+ regnums = mallocarray(vmregset->count, sizeof(regnums[0]),
+ M_VMMDEV, M_WAITOK);
error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) *
vmregset->count);
if (error == 0)
@@ -682,10 +689,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
error = EINVAL;
break;
}
- regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV,
- M_WAITOK);
- regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV,
- M_WAITOK);
+ regvals = mallocarray(vmregset->count, sizeof(regvals[0]),
+ M_VMMDEV, M_WAITOK);
+ regnums = mallocarray(vmregset->count, sizeof(regnums[0]),
+ M_VMMDEV, M_WAITOK);
error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) *
vmregset->count);
if (error == 0)
diff --git a/sys/dev/vmm/vmm_dev.h b/sys/dev/vmm/vmm_dev.h
index 410066c49cf2..2881a7063565 100644
--- a/sys/dev/vmm/vmm_dev.h
+++ b/sys/dev/vmm/vmm_dev.h
@@ -44,6 +44,7 @@ struct vmmdev_ioctl {
#define VMMDEV_IOCTL_LOCK_ALL_VCPUS 0x08
#define VMMDEV_IOCTL_ALLOC_VCPU 0x10
#define VMMDEV_IOCTL_MAYBE_ALLOC_VCPU 0x20
+#define VMMDEV_IOCTL_PRIV_CHECK_DRIVER 0x40
int flags;
};
diff --git a/sys/fs/cuse/cuse.c b/sys/fs/cuse/cuse.c
index d63a7d4691cf..b2524324584a 100644
--- a/sys/fs/cuse/cuse.c
+++ b/sys/fs/cuse/cuse.c
@@ -195,12 +195,14 @@ static const struct filterops cuse_client_kqfilter_read_ops = {
.f_isfd = 1,
.f_detach = cuse_client_kqfilter_read_detach,
.f_event = cuse_client_kqfilter_read_event,
+ .f_copy = knote_triv_copy,
};
static const struct filterops cuse_client_kqfilter_write_ops = {
.f_isfd = 1,
.f_detach = cuse_client_kqfilter_write_detach,
.f_event = cuse_client_kqfilter_write_event,
+ .f_copy = knote_triv_copy,
};
static d_open_t cuse_client_open;
diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c
index 57b3559731f7..75bc0357571f 100644
--- a/sys/fs/fuse/fuse_device.c
+++ b/sys/fs/fuse/fuse_device.c
@@ -126,11 +126,13 @@ static const struct filterops fuse_device_rfiltops = {
.f_isfd = 1,
.f_detach = fuse_device_filt_detach,
.f_event = fuse_device_filt_read,
+ .f_copy = knote_triv_copy,
};
static const struct filterops fuse_device_wfiltops = {
.f_isfd = 1,
.f_event = fuse_device_filt_write,
+ .f_copy = knote_triv_copy,
};
/****************************
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 7f5b29ca2085..ec95716ea485 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -216,10 +216,17 @@ NFSD_VNET_DEFINE_STATIC(u_char *, nfsrv_dnsname) = NULL;
* marked 0 in this array, the code will still work, just not quite as
* efficiently.)
*/
-static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
+static bool nfs_bigreply[NFSV42_NPROCS] = {
+ [NFSPROC_GETACL] = true,
+ [NFSPROC_GETEXTATTR] = true,
+ [NFSPROC_LISTEXTATTR] = true,
+ [NFSPROC_LOOKUP] = true,
+ [NFSPROC_READ] = true,
+ [NFSPROC_READDIR] = true,
+ [NFSPROC_READDIRPLUS] = true,
+ [NFSPROC_READDS] = true,
+ [NFSPROC_READLINK] = true,
+};
/* local functions */
static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
@@ -232,6 +239,8 @@ static int nfsrv_getrefstr(struct nfsrv_descript *, u_char **, u_char **,
static void nfsrv_refstrbigenough(int, u_char **, u_char **, int *);
static uint32_t vtonfsv4_type(struct vattr *);
static __enum_uint8(vtype) nfsv4tov_type(uint32_t, uint16_t *);
+static void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
+ struct nfsclsession *, bool, struct ucred *);
static struct {
int op;
@@ -5021,9 +5030,9 @@ nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, int repstat,
/*
* Generate the xdr for an NFSv4.1 Sequence Operation.
*/
-void
+static void
nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
- struct nfsclsession *sep, int dont_replycache, struct ucred *cred)
+ struct nfsclsession *sep, bool dont_replycache, struct ucred *cred)
{
uint32_t *tl, slotseq = 0;
int error, maxslot, slotpos;
@@ -5054,7 +5063,7 @@ nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
*tl++ = txdr_unsigned(slotseq);
*tl++ = txdr_unsigned(slotpos);
*tl++ = txdr_unsigned(maxslot);
- if (dont_replycache == 0)
+ if (!dont_replycache)
*tl = newnfs_true;
else
*tl = newnfs_false;
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 61083ecf2d66..16a76c060e78 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -361,8 +361,6 @@ int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_in *,
int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
struct mbuf **, uint16_t);
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **);
-void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
- struct nfsclsession *, int, struct ucred *);
int nfsv4_sequencelookup(struct nfsmount *, struct nfsclsession *, int *,
int *, uint32_t *, uint8_t *, bool);
void nfsv4_freeslot(struct nfsclsession *, int, bool);
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 27c65f15d5e3..db0bc77a752f 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -82,6 +82,7 @@ static const struct filterops gdev_filterops_vnode = {
.f_isfd = 1,
.f_detach = gdev_filter_detach,
.f_event = gdev_filter_vnode,
+ .f_copy = knote_triv_copy,
};
static struct cdevsw g_dev_cdevsw = {
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index 13769af0fbca..14c942942d08 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -92,7 +92,7 @@ struct sysentvec elf32_freebsd_sysvec = {
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
-static Elf32_Brandinfo freebsd_brand_info = {
+static const Elf32_Brandinfo freebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_386,
.compat_3_brand = "FreeBSD",
@@ -103,11 +103,11 @@ static Elf32_Brandinfo freebsd_brand_info = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
+C_SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info);
-static Elf32_Brandinfo freebsd_brand_oinfo = {
+static const Elf32_Brandinfo freebsd_brand_oinfo = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_386,
.compat_3_brand = "FreeBSD",
@@ -118,11 +118,11 @@ static Elf32_Brandinfo freebsd_brand_oinfo = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
+C_SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_oinfo);
-static Elf32_Brandinfo kfreebsd_brand_info = {
+static const Elf32_Brandinfo kfreebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_386,
.compat_3_brand = "FreeBSD",
@@ -133,7 +133,7 @@ static Elf32_Brandinfo kfreebsd_brand_info = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY
};
-SYSINIT(kelf32, SI_SUB_EXEC, SI_ORDER_ANY,
+C_SYSINIT(kelf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&kfreebsd_brand_info);
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 85877bf40997..14b5f64388d2 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -796,7 +796,7 @@ linux_vdso_reloc(char *mapping, Elf_Addr offset)
}
}
-static Elf_Brandnote linux_brandnote = {
+static const Elf_Brandnote linux_brandnote = {
.hdr.n_namesz = sizeof(GNU_ABI_VENDOR),
.hdr.n_descsz = 16, /* XXX at least 16 */
.hdr.n_type = 1,
@@ -805,7 +805,7 @@ static Elf_Brandnote linux_brandnote = {
.trans_osrel = linux_trans_osrel
};
-static Elf32_Brandinfo linux_brand = {
+static const Elf32_Brandinfo linux_brand = {
.brand = ELFOSABI_LINUX,
.machine = EM_386,
.compat_3_brand = "Linux",
@@ -816,7 +816,7 @@ static Elf32_Brandinfo linux_brand = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-static Elf32_Brandinfo linux_glibc2brand = {
+static const Elf32_Brandinfo linux_glibc2brand = {
.brand = ELFOSABI_LINUX,
.machine = EM_386,
.compat_3_brand = "Linux",
@@ -827,7 +827,7 @@ static Elf32_Brandinfo linux_glibc2brand = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-static Elf32_Brandinfo linux_muslbrand = {
+static const Elf32_Brandinfo linux_muslbrand = {
.brand = ELFOSABI_LINUX,
.machine = EM_386,
.compat_3_brand = "Linux",
@@ -839,7 +839,7 @@ static Elf32_Brandinfo linux_muslbrand = {
LINUX_BI_FUTEX_REQUEUE
};
-Elf32_Brandinfo *linux_brandlist[] = {
+const Elf32_Brandinfo *linux_brandlist[] = {
&linux_brand,
&linux_glibc2brand,
&linux_muslbrand,
@@ -849,7 +849,7 @@ Elf32_Brandinfo *linux_brandlist[] = {
static int
linux_elf_modevent(module_t mod, int type, void *data)
{
- Elf32_Brandinfo **brandinfo;
+ const Elf32_Brandinfo **brandinfo;
int error;
struct linux_ioctl_handler **lihp;
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index a1fabbc86f27..779158b41221 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -231,7 +231,7 @@ static const Elf_Brandinfo *elf_brand_list[MAX_BRANDS];
#define aligned(a, t) (rounddown2((u_long)(a), sizeof(t)) == (u_long)(a))
-Elf_Brandnote __elfN(freebsd_brandnote) = {
+const Elf_Brandnote __elfN(freebsd_brandnote) = {
.hdr.n_namesz = sizeof(FREEBSD_ABI_VENDOR),
.hdr.n_descsz = sizeof(int32_t),
.hdr.n_type = NT_FREEBSD_ABI_TAG,
@@ -254,7 +254,7 @@ __elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel)
static int GNU_KFREEBSD_ABI_DESC = 3;
-Elf_Brandnote __elfN(kfreebsd_brandnote) = {
+const Elf_Brandnote __elfN(kfreebsd_brandnote) = {
.hdr.n_namesz = sizeof(GNU_ABI_VENDOR),
.hdr.n_descsz = 16, /* XXX at least 16 */
.hdr.n_type = 1,
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 19118eb7f275..a71a601733e5 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2486,7 +2486,7 @@ fdunshare(struct thread *td)
if (refcount_load(&p->p_fd->fd_refcnt) == 1)
return;
- tmp = fdcopy(p->p_fd);
+ tmp = fdcopy(p->p_fd, p);
fdescfree(td);
p->p_fd = tmp;
}
@@ -2515,14 +2515,17 @@ pdunshare(struct thread *td)
* this is to ease callers, not catch errors.
*/
struct filedesc *
-fdcopy(struct filedesc *fdp)
+fdcopy(struct filedesc *fdp, struct proc *p1)
{
struct filedesc *newfdp;
struct filedescent *nfde, *ofde;
+ struct file *fp;
int i, lastfile;
+ bool fork_pass;
MPASS(fdp != NULL);
+ fork_pass = false;
newfdp = fdinit();
FILEDESC_SLOCK(fdp);
for (;;) {
@@ -2533,10 +2536,35 @@ fdcopy(struct filedesc *fdp)
fdgrowtable(newfdp, lastfile + 1);
FILEDESC_SLOCK(fdp);
}
- /* copy all passable descriptors (i.e. not kqueue) */
+
+ /*
+ * Copy all passable descriptors (i.e. not kqueue), and
+ * prepare to handle copyable but not passable descriptors
+ * (kqueues).
+ *
+ * The pass to handle copying is performed after all passable
+ * files are installed into the new file descriptor's table,
+ * since kqueues need all referenced file descriptors already
+ * valid, including other kqueues. For the same reason the
+ * copying is done in two passes by itself, first installing
+ * not fully initialized ('empty') copyable files into the new
+ * fd table, and then giving the subsystems a second chance to
+ * really fill the copied file backing structure with the
+ * content.
+ */
newfdp->fd_freefile = fdp->fd_freefile;
FILEDESC_FOREACH_FDE(fdp, i, ofde) {
- if ((ofde->fde_file->f_ops->fo_flags & DFLAG_PASSABLE) == 0 ||
+ const struct fileops *ops;
+
+ ops = ofde->fde_file->f_ops;
+ fp = NULL;
+ if ((ops->fo_flags & DFLAG_FORK) != 0 &&
+ (ofde->fde_flags & UF_FOCLOSE) == 0) {
+ if (ops->fo_fork(newfdp, ofde->fde_file, &fp, p1,
+ curthread) != 0)
+ continue;
+ fork_pass = true;
+ } else if ((ops->fo_flags & DFLAG_PASSABLE) == 0 ||
(ofde->fde_flags & UF_FOCLOSE) != 0 ||
!fhold(ofde->fde_file)) {
if (newfdp->fd_freefile == fdp->fd_freefile)
@@ -2545,11 +2573,30 @@ fdcopy(struct filedesc *fdp)
}
nfde = &newfdp->fd_ofiles[i];
*nfde = *ofde;
+ if (fp != NULL)
+ nfde->fde_file = fp;
filecaps_copy(&ofde->fde_caps, &nfde->fde_caps, true);
fdused_init(newfdp, i);
}
MPASS(newfdp->fd_freefile != -1);
FILEDESC_SUNLOCK(fdp);
+
+ /*
+ * Now handle copying kqueues, since all fds, including
+ * kqueues, are in place.
+ */
+ if (__predict_false(fork_pass)) {
+ FILEDESC_FOREACH_FDE(newfdp, i, nfde) {
+ const struct fileops *ops;
+
+ ops = nfde->fde_file->f_ops;
+ if ((ops->fo_flags & DFLAG_FORK) == 0 ||
+ nfde->fde_file == NULL)
+ continue;
+ ops->fo_fork(newfdp, NULL, &nfde->fde_file, p1,
+ curthread);
+ }
+ }
return (newfdp);
}
diff --git a/sys/kern/kern_devctl.c b/sys/kern/kern_devctl.c
index a1696225df32..a37cb23efed8 100644
--- a/sys/kern/kern_devctl.c
+++ b/sys/kern/kern_devctl.c
@@ -130,6 +130,7 @@ static const struct filterops devctl_rfiltops = {
.f_isfd = 1,
.f_detach = filt_devctl_detach,
.f_event = filt_devctl_read,
+ .f_copy = knote_triv_copy,
};
static struct cdev *devctl_dev;
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index a6333d8011b1..1baa24d278bf 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -134,6 +134,7 @@ static fo_kqfilter_t kqueue_kqfilter;
static fo_stat_t kqueue_stat;
static fo_close_t kqueue_close;
static fo_fill_kinfo_t kqueue_fill_kinfo;
+static fo_fork_t kqueue_fork;
static const struct fileops kqueueops = {
.fo_read = invfo_rdwr,
@@ -148,7 +149,9 @@ static const struct fileops kqueueops = {
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
.fo_cmp = file_kcmp_generic,
+ .fo_fork = kqueue_fork,
.fo_fill_kinfo = kqueue_fill_kinfo,
+ .fo_flags = DFLAG_FORK,
};
static int knote_attach(struct knote *kn, struct kqueue *kq);
@@ -176,6 +179,7 @@ static void filt_timerdetach(struct knote *kn);
static void filt_timerstart(struct knote *kn, sbintime_t to);
static void filt_timertouch(struct knote *kn, struct kevent *kev,
u_long type);
+static int filt_timercopy(struct knote *kn, struct proc *p1);
static int filt_timervalidate(struct knote *kn, sbintime_t *to);
static int filt_timer(struct knote *kn, long hint);
static int filt_userattach(struct knote *kn);
@@ -187,11 +191,13 @@ static void filt_usertouch(struct knote *kn, struct kevent *kev,
static const struct filterops file_filtops = {
.f_isfd = 1,
.f_attach = filt_fileattach,
+ .f_copy = knote_triv_copy,
};
static const struct filterops kqread_filtops = {
.f_isfd = 1,
.f_detach = filt_kqdetach,
.f_event = filt_kqueue,
+ .f_copy = knote_triv_copy,
};
/* XXX - move to kern_proc.c? */
static const struct filterops proc_filtops = {
@@ -199,12 +205,14 @@ static const struct filterops proc_filtops = {
.f_attach = filt_procattach,
.f_detach = filt_procdetach,
.f_event = filt_proc,
+ .f_copy = knote_triv_copy,
};
static const struct filterops jail_filtops = {
.f_isfd = 0,
.f_attach = filt_jailattach,
.f_detach = filt_jaildetach,
.f_event = filt_jail,
+ .f_copy = knote_triv_copy,
};
static const struct filterops timer_filtops = {
.f_isfd = 0,
@@ -212,12 +220,14 @@ static const struct filterops timer_filtops = {
.f_detach = filt_timerdetach,
.f_event = filt_timer,
.f_touch = filt_timertouch,
+ .f_copy = filt_timercopy,
};
static const struct filterops user_filtops = {
.f_attach = filt_userattach,
.f_detach = filt_userdetach,
.f_event = filt_user,
.f_touch = filt_usertouch,
+ .f_copy = knote_triv_copy,
};
static uma_zone_t knote_zone;
@@ -347,6 +357,7 @@ filt_nullattach(struct knote *kn)
static const struct filterops null_filtops = {
.f_isfd = 0,
.f_attach = filt_nullattach,
+ .f_copy = knote_triv_copy,
};
/* XXX - make SYSINIT to add these, and move into respective modules. */
@@ -940,6 +951,30 @@ filt_timerattach(struct knote *kn)
return (0);
}
+static int
+filt_timercopy(struct knote *kn, struct proc *p)
+{
+ struct kq_timer_cb_data *kc_src, *kc;
+
+ if (atomic_fetchadd_int(&kq_ncallouts, 1) + 1 > kq_calloutmax) {
+ atomic_subtract_int(&kq_ncallouts, 1);
+ return (ENOMEM);
+ }
+
+ kn->kn_status &= ~KN_DETACHED;
+ kc_src = kn->kn_ptr.p_v;
+ kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK);
+ kc->kn = kn;
+ kc->p = p;
+ kc->flags = kc_src->flags & ~KQ_TIMER_CB_ENQUEUED;
+ kc->next = kc_src->next;
+ kc->to = kc_src->to;
+ kc->cpuid = PCPU_GET(cpuid);
+ callout_init(&kc->c, 1);
+ kqtimer_sched_callout(kc);
+ return (0);
+}
+
static void
filt_timerstart(struct knote *kn, sbintime_t to)
{
@@ -1151,7 +1186,7 @@ int
sys_kqueue(struct thread *td, struct kqueue_args *uap)
{
- return (kern_kqueue(td, 0, NULL));
+ return (kern_kqueue(td, 0, false, NULL));
}
int
@@ -1159,55 +1194,76 @@ sys_kqueuex(struct thread *td, struct kqueuex_args *uap)
{
int flags;
- if ((uap->flags & ~(KQUEUE_CLOEXEC)) != 0)
+ if ((uap->flags & ~(KQUEUE_CLOEXEC | KQUEUE_CPONFORK)) != 0)
return (EINVAL);
flags = 0;
if ((uap->flags & KQUEUE_CLOEXEC) != 0)
flags |= O_CLOEXEC;
- return (kern_kqueue(td, flags, NULL));
+ return (kern_kqueue(td, flags, (uap->flags & KQUEUE_CPONFORK) != 0,
+ NULL));
}
static void
-kqueue_init(struct kqueue *kq)
+kqueue_init(struct kqueue *kq, bool cponfork)
{
mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF | MTX_DUPOK);
TAILQ_INIT(&kq->kq_head);
knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock);
TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
+ if (cponfork)
+ kq->kq_state |= KQ_CPONFORK;
}
-int
-kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
+static int
+kern_kqueue_alloc(struct thread *td, struct filedesc *fdp, int *fdip,
+ struct file **fpp, int flags, struct filecaps *fcaps, bool cponfork,
+ struct kqueue **kqp)
{
- struct filedesc *fdp;
- struct kqueue *kq;
- struct file *fp;
struct ucred *cred;
- int fd, error;
+ struct kqueue *kq;
+ int error;
- fdp = td->td_proc->p_fd;
cred = td->td_ucred;
if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES)))
return (ENOMEM);
- error = falloc_caps(td, &fp, &fd, flags, fcaps);
+ error = fdip != NULL ? falloc_caps(td, fpp, fdip, flags, fcaps) :
+ _falloc_noinstall(td, fpp, 1);
if (error != 0) {
chgkqcnt(cred->cr_ruidinfo, -1, 0);
return (error);
}
/* An extra reference on `fp' has been held for us by falloc(). */
- kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO);
- kqueue_init(kq);
+ kq = malloc(sizeof(*kq), M_KQUEUE, M_WAITOK | M_ZERO);
+ kqueue_init(kq, cponfork);
kq->kq_fdp = fdp;
kq->kq_cred = crhold(cred);
- FILEDESC_XLOCK(fdp);
+ if (fdip != NULL)
+ FILEDESC_XLOCK(fdp);
TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
- FILEDESC_XUNLOCK(fdp);
+ if (fdip != NULL)
+ FILEDESC_XUNLOCK(fdp);
+
+ finit(*fpp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops);
+ *kqp = kq;
+ return (0);
+}
+
+int
+kern_kqueue(struct thread *td, int flags, bool cponfork, struct filecaps *fcaps)
+{
+ struct kqueue *kq;
+ struct file *fp;
+ int fd, error;
+
+ error = kern_kqueue_alloc(td, td->td_proc->p_fd, &fd, &fp, flags,
+ fcaps, cponfork, &kq);
+ if (error != 0)
+ return (error);
- finit(fp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops);
fdrop(fp, td);
td->td_retval[0] = fd;
@@ -1488,7 +1544,7 @@ kern_kevent_anonymous(struct thread *td, int nevents,
struct kqueue kq = {};
int error;
- kqueue_init(&kq);
+ kqueue_init(&kq, false);
kq.kq_refcnt = 1;
error = kqueue_kevent(&kq, td, nevents, nevents, k_ops, NULL);
kqueue_drain(&kq, td);
@@ -1576,7 +1632,7 @@ kqueue_fo_release(int filt)
mtx_lock(&filterops_lock);
KASSERT(sysfilt_ops[~filt].for_refcnt > 0,
- ("filter object refcount not valid on release"));
+ ("filter object %d refcount not valid on release", filt));
sysfilt_ops[~filt].for_refcnt--;
mtx_unlock(&filterops_lock);
}
@@ -1855,17 +1911,8 @@ done:
}
static int
-kqueue_acquire(struct file *fp, struct kqueue **kqp)
+kqueue_acquire_ref(struct kqueue *kq)
{
- int error;
- struct kqueue *kq;
-
- error = 0;
-
- kq = fp->f_data;
- if (fp->f_type != DTYPE_KQUEUE || kq == NULL)
- return (EINVAL);
- *kqp = kq;
KQ_LOCK(kq);
if ((kq->kq_state & KQ_CLOSING) == KQ_CLOSING) {
KQ_UNLOCK(kq);
@@ -1873,8 +1920,22 @@ kqueue_acquire(struct file *fp, struct kqueue **kqp)
}
kq->kq_refcnt++;
KQ_UNLOCK(kq);
+ return (0);
+}
- return error;
+static int
+kqueue_acquire(struct file *fp, struct kqueue **kqp)
+{
+ struct kqueue *kq;
+ int error;
+
+ kq = fp->f_data;
+ if (fp->f_type != DTYPE_KQUEUE || kq == NULL)
+ return (EINVAL);
+ error = kqueue_acquire_ref(kq);
+ if (error == 0)
+ *kqp = kq;
+ return (error);
}
static void
@@ -2937,6 +2998,152 @@ noacquire:
return (error);
}
+static int
+kqueue_fork_alloc(struct filedesc *fdp, struct file *fp, struct file **fp1,
+ struct thread *td)
+{
+ struct kqueue *kq, *kq1;
+ int error;
+
+ MPASS(fp->f_type == DTYPE_KQUEUE);
+ kq = fp->f_data;
+ if ((kq->kq_state & KQ_CPONFORK) == 0)
+ return (EOPNOTSUPP);
+ error = kqueue_acquire_ref(kq);
+ if (error != 0)
+ return (error);
+ error = kern_kqueue_alloc(td, fdp, NULL, fp1, 0, NULL, true, &kq1);
+ if (error == 0) {
+ kq1->kq_forksrc = kq;
+ (*fp1)->f_flag = fp->f_flag & (FREAD | FWRITE | FEXEC |
+ O_CLOEXEC | O_CLOFORK);
+ } else {
+ kqueue_release(kq, 0);
+ }
+ return (error);
+}
+
+static void
+kqueue_fork_copy_knote(struct kqueue *kq1, struct knote *kn, struct proc *p1,
+ struct filedesc *fdp)
+{
+ struct knote *kn1;
+ const struct filterops *fop;
+ int error;
+
+ fop = kn->kn_fop;
+ if (fop->f_copy == NULL || (fop->f_isfd &&
+ fdp->fd_files->fdt_ofiles[kn->kn_kevent.ident].fde_file == NULL))
+ return;
+ error = kqueue_expand(kq1, fop, kn->kn_kevent.ident, M_WAITOK);
+ if (error != 0)
+ return;
+
+ kn1 = knote_alloc(M_WAITOK);
+ *kn1 = *kn;
+ kn1->kn_status |= KN_DETACHED;
+ kn1->kn_status &= ~KN_QUEUED;
+ kn1->kn_kq = kq1;
+ error = fop->f_copy(kn1, p1);
+ if (error != 0) {
+ knote_free(kn1);
+ return;
+ }
+ (void)kqueue_fo_find(kn->kn_kevent.filter);
+ if (fop->f_isfd && !fhold(kn1->kn_fp)) {
+ fop->f_detach(kn1);
+ kqueue_fo_release(kn->kn_kevent.filter);
+ knote_free(kn1);
+ return;
+ }
+ if (kn->kn_knlist != NULL)
+ knlist_add(kn->kn_knlist, kn1, 0);
+ KQ_LOCK(kq1);
+ knote_attach(kn1, kq1);
+ kn1->kn_influx = 0;
+ if ((kn->kn_status & KN_QUEUED) != 0)
+ knote_enqueue(kn1);
+ KQ_UNLOCK(kq1);
+}
+
+static void
+kqueue_fork_copy_list(struct klist *knlist, struct knote *marker,
+ struct kqueue *kq, struct kqueue *kq1, struct proc *p1,
+ struct filedesc *fdp)
+{
+ struct knote *kn;
+
+ KQ_OWNED(kq);
+ kn = SLIST_FIRST(knlist);
+ while (kn != NULL) {
+ if ((kn->kn_status & KN_DETACHED) != 0 ||
+ (kn_in_flux(kn) && (kn->kn_status & KN_SCAN) == 0)) {
+ kn = SLIST_NEXT(kn, kn_link);
+ continue;
+ }
+ kn_enter_flux(kn);
+ SLIST_INSERT_AFTER(kn, marker, kn_link);
+ KQ_UNLOCK(kq);
+ kqueue_fork_copy_knote(kq1, kn, p1, fdp);
+ KQ_LOCK(kq);
+ kn_leave_flux(kn);
+ kn = SLIST_NEXT(marker, kn_link);
+ /* XXXKIB switch kn_link to LIST? */
+ SLIST_REMOVE(knlist, marker, knote, kn_link);
+ }
+}
+
+static int
+kqueue_fork_copy(struct filedesc *fdp, struct file *fp, struct file *fp1,
+ struct proc *p1, struct thread *td)
+{
+ struct kqueue *kq, *kq1;
+ struct knote *marker;
+ int error, i;
+
+ error = 0;
+ MPASS(fp == NULL);
+ MPASS(fp1->f_type == DTYPE_KQUEUE);
+
+ kq1 = fp1->f_data;
+ kq = kq1->kq_forksrc;
+ marker = knote_alloc(M_WAITOK);
+ marker->kn_status = KN_MARKER;
+
+ KQ_LOCK(kq);
+ for (i = 0; i < kq->kq_knlistsize; i++) {
+ kqueue_fork_copy_list(&kq->kq_knlist[i], marker, kq, kq1,
+ p1, fdp);
+ }
+ if (kq->kq_knhashmask != 0) {
+ for (i = 0; i <= kq->kq_knhashmask; i++) {
+ kqueue_fork_copy_list(&kq->kq_knhash[i], marker, kq,
+ kq1, p1, fdp);
+ }
+ }
+ kqueue_release(kq, 1);
+ kq1->kq_forksrc = NULL;
+ KQ_UNLOCK(kq);
+
+ knote_free(marker);
+ return (error);
+}
+
+static int
+kqueue_fork(struct filedesc *fdp, struct file *fp, struct file **fp1,
+ struct proc *p1, struct thread *td)
+{
+ if (*fp1 == NULL)
+ return (kqueue_fork_alloc(fdp, fp, fp1, td));
+ return (kqueue_fork_copy(fdp, fp, *fp1, p1, td));
+}
+
+int
+knote_triv_copy(struct knote *kn __unused, struct proc *p1 __unused)
+{
+ return (0);
+}
+
struct knote_status_export_bit {
int kn_status_bit;
int knt_status_bit;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 7f6abae187b3..8b237b6dbd17 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -423,7 +423,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
pd = pdshare(p1->p_pd);
else
pd = pdcopy(p1->p_pd);
- fd = fdcopy(p1->p_fd);
+ fd = fdcopy(p1->p_fd, p2);
fdtol = NULL;
} else {
if (fr->fr_flags2 & FR2_SHARE_PATHS)
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 3697d95fe0e5..267b60ffb5bc 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -1088,6 +1088,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
else {
if (!(flags & (JAIL_USE_DESC | JAIL_AT_DESC | JAIL_GET_DESC |
JAIL_OWN_DESC))) {
+ error = EINVAL;
vfs_opterror(opts, "unexpected desc");
goto done_errmsg;
}
@@ -2518,6 +2519,7 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
} else if (error == 0) {
if (!(flags & (JAIL_USE_DESC | JAIL_AT_DESC | JAIL_GET_DESC |
JAIL_OWN_DESC))) {
+ error = EINVAL;
vfs_opterror(opts, "unexpected desc");
goto done;
}
@@ -2909,12 +2911,6 @@ prison_remove(struct prison *pr)
{
sx_assert(&allprison_lock, SA_XLOCKED);
mtx_assert(&pr->pr_mtx, MA_OWNED);
- if (!prison_isalive(pr)) {
- /* Silently ignore already-dying prisons. */
- mtx_unlock(&pr->pr_mtx);
- sx_xunlock(&allprison_lock);
- return;
- }
prison_deref(pr, PD_KILL | PD_DEREF | PD_LOCKED | PD_LIST_XLOCKED);
}
@@ -3461,12 +3457,17 @@ prison_deref(struct prison *pr, int flags)
/* Kill the prison and its descendents. */
KASSERT(pr != &prison0,
("prison_deref trying to kill prison0"));
- if (!(flags & PD_DEREF)) {
- prison_hold(pr);
- flags |= PD_DEREF;
+ if (!prison_isalive(pr)) {
+ /* Silently ignore already-dying prisons. */
+ flags &= ~PD_KILL;
+ } else {
+ if (!(flags & PD_DEREF)) {
+ prison_hold(pr);
+ flags |= PD_DEREF;
+ }
+ flags = prison_lock_xlock(pr, flags);
+ prison_deref_kill(pr, &freeprison);
}
- flags = prison_lock_xlock(pr, flags);
- prison_deref_kill(pr, &freeprison);
}
if (flags & PD_DEUREF) {
/* Drop a user reference. */
diff --git a/sys/kern/kern_jaildesc.c b/sys/kern/kern_jaildesc.c
index 3f322b271400..a564393d3366 100644
--- a/sys/kern/kern_jaildesc.c
+++ b/sys/kern/kern_jaildesc.c
@@ -344,6 +344,7 @@ static const struct filterops jaildesc_kqops = {
.f_isfd = 1,
.f_detach = jaildesc_kqops_detach,
.f_event = jaildesc_kqops_event,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 21f765b17f62..a55f3c761449 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -124,6 +124,7 @@ const struct filterops sig_filtops = {
.f_attach = filt_sigattach,
.f_detach = filt_sigdetach,
.f_event = filt_signal,
+ .f_copy = knote_triv_copy,
};
static int kern_forcesigexit = 1;
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c
index 56264a96c9fa..909dd10a6e69 100644
--- a/sys/kern/subr_kdb.c
+++ b/sys/kern/subr_kdb.c
@@ -330,7 +330,7 @@ kdb_reboot(void)
#define KEY_CRTLP 16 /* ^P */
#define KEY_CRTLR 18 /* ^R */
-/* States of th KDB "alternate break sequence" detecting state machine. */
+/* States of the KDB "alternate break sequence" detecting state machine. */
enum {
KDB_ALT_BREAK_SEEN_NONE,
KDB_ALT_BREAK_SEEN_CR,
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c
index 5380902e602f..aac35a56130e 100644
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -79,6 +79,7 @@ static const struct filterops log_read_filterops = {
.f_attach = NULL,
.f_detach = logkqdetach,
.f_event = logkqread,
+ .f_copy = knote_triv_copy,
};
static struct logsoftc {
diff --git a/sys/kern/sys_eventfd.c b/sys/kern/sys_eventfd.c
index c2a0f67cae85..04ed107c933d 100644
--- a/sys/kern/sys_eventfd.c
+++ b/sys/kern/sys_eventfd.c
@@ -85,13 +85,16 @@ static int filt_eventfdwrite(struct knote *kn, long hint);
static const struct filterops eventfd_rfiltops = {
.f_isfd = 1,
.f_detach = filt_eventfddetach,
- .f_event = filt_eventfdread
+ .f_event = filt_eventfdread,
+ .f_copy = knote_triv_copy,
};
+
static const struct filterops eventfd_wfiltops = {
.f_isfd = 1,
.f_detach = filt_eventfddetach,
- .f_event = filt_eventfdwrite
+ .f_event = filt_eventfdwrite,
+ .f_copy = knote_triv_copy,
};
struct eventfd {
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 57ebe8dc85f0..6531cea31423 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -181,20 +181,23 @@ static int filt_pipedump(struct proc *p, struct knote *kn,
static const struct filterops pipe_nfiltops = {
.f_isfd = 1,
.f_detach = filt_pipedetach_notsup,
- .f_event = filt_pipenotsup
+ .f_event = filt_pipenotsup,
/* no userdump */
+ .f_copy = knote_triv_copy,
};
static const struct filterops pipe_rfiltops = {
.f_isfd = 1,
.f_detach = filt_pipedetach,
.f_event = filt_piperead,
.f_userdump = filt_pipedump,
+ .f_copy = knote_triv_copy,
};
static const struct filterops pipe_wfiltops = {
.f_isfd = 1,
.f_detach = filt_pipedetach,
.f_event = filt_pipewrite,
.f_userdump = filt_pipedump,
+ .f_copy = knote_triv_copy,
};
/*
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
index acaf1241cb2e..c5db21544b0f 100644
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -486,6 +486,7 @@ static const struct filterops procdesc_kqops = {
.f_isfd = 1,
.f_detach = procdesc_kqops_detach,
.f_event = procdesc_kqops_event,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index c8e2c561b7cf..067471eb949a 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -754,12 +754,14 @@ static const struct filterops tty_kqops_read = {
.f_isfd = 1,
.f_detach = tty_kqops_read_detach,
.f_event = tty_kqops_read_event,
+ .f_copy = knote_triv_copy,
};
static const struct filterops tty_kqops_write = {
.f_isfd = 1,
.f_detach = tty_kqops_write_detach,
.f_event = tty_kqops_write_event,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index 1291770a9ccb..2672935c2d89 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -491,11 +491,13 @@ static const struct filterops pts_kqops_read = {
.f_isfd = 1,
.f_detach = pts_kqops_read_detach,
.f_event = pts_kqops_read_event,
+ .f_copy = knote_triv_copy,
};
static const struct filterops pts_kqops_write = {
.f_isfd = 1,
.f_detach = pts_kqops_write_detach,
.f_event = pts_kqops_write_event,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index a8aec397b352..4c1bb1ff228e 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -281,11 +281,13 @@ static const struct filterops mq_rfiltops = {
.f_isfd = 1,
.f_detach = filt_mqdetach,
.f_event = filt_mqread,
+ .f_copy = knote_triv_copy,
};
static const struct filterops mq_wfiltops = {
.f_isfd = 1,
.f_detach = filt_mqdetach,
.f_event = filt_mqwrite,
+ .f_copy = knote_triv_copy,
};
/*
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index fe2d8d056062..eb9544628137 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -191,16 +191,19 @@ static const struct filterops soread_filtops = {
.f_isfd = 1,
.f_detach = filt_sordetach,
.f_event = filt_soread,
+ .f_copy = knote_triv_copy,
};
static const struct filterops sowrite_filtops = {
.f_isfd = 1,
.f_detach = filt_sowdetach,
.f_event = filt_sowrite,
+ .f_copy = knote_triv_copy,
};
static const struct filterops soempty_filtops = {
.f_isfd = 1,
.f_detach = filt_sowdetach,
.f_event = filt_soempty,
+ .f_copy = knote_triv_copy,
};
so_gen_t so_gencnt; /* generation count for sockets */
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 90489e99491a..807271488af2 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1855,11 +1855,13 @@ static const struct filterops uipc_write_filtops = {
.f_isfd = 1,
.f_detach = uipc_filt_sowdetach,
.f_event = uipc_filt_sowrite,
+ .f_copy = knote_triv_copy,
};
static const struct filterops uipc_empty_filtops = {
.f_isfd = 1,
.f_detach = uipc_filt_sowdetach,
.f_event = uipc_filt_soempty,
+ .f_copy = knote_triv_copy,
};
static int
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index e63fa4c01434..60916a9fbd32 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -345,12 +345,14 @@ static const struct filterops aio_filtops = {
.f_attach = filt_aioattach,
.f_detach = filt_aiodetach,
.f_event = filt_aio,
+ .f_copy = knote_triv_copy,
};
static const struct filterops lio_filtops = {
.f_isfd = 0,
.f_attach = filt_lioattach,
.f_detach = filt_liodetach,
- .f_event = filt_lio
+ .f_event = filt_lio,
+ .f_copy = knote_triv_copy,
};
static eventhandler_tag exit_tag, exec_tag;
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index 2e397b8e9e8f..b674313993c4 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -260,8 +260,10 @@ cluster_read(struct vnode *vp, u_quad_t filesize, daddr_t lblkno, long size,
*/
while (lblkno < (origblkno + maxra)) {
error = VOP_BMAP(vp, lblkno, NULL, &blkno, &ncontig, NULL);
- if (error)
+ if (error) {
+ error = 0;
break;
+ }
if (blkno == -1)
break;
diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c
index b265a5ff3a62..e60d8426ee42 100644
--- a/sys/kern/vfs_inotify.c
+++ b/sys/kern/vfs_inotify.c
@@ -111,6 +111,7 @@ static const struct filterops inotify_rfiltops = {
.f_isfd = 1,
.f_detach = filt_inotifydetach,
.f_event = filt_inotifyevent,
+ .f_copy = knote_triv_copy,
};
static MALLOC_DEFINE(M_INOTIFY, "inotify", "inotify data structures");
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 73e110c05bc1..58975f7ac932 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -6545,6 +6545,7 @@ const struct filterops fs_filtops = {
.f_attach = filt_fsattach,
.f_detach = filt_fsdetach,
.f_event = filt_fsevent,
+ .f_copy = knote_triv_copy,
};
static int
@@ -6624,24 +6625,28 @@ static int filt_vfsvnode(struct knote *kn, long hint);
static void filt_vfsdetach(struct knote *kn);
static int filt_vfsdump(struct proc *p, struct knote *kn,
struct kinfo_knote *kin);
+static int filt_vfscopy(struct knote *kn, struct proc *p1);
static const struct filterops vfsread_filtops = {
.f_isfd = 1,
.f_detach = filt_vfsdetach,
.f_event = filt_vfsread,
.f_userdump = filt_vfsdump,
+ .f_copy = filt_vfscopy,
};
static const struct filterops vfswrite_filtops = {
.f_isfd = 1,
.f_detach = filt_vfsdetach,
.f_event = filt_vfswrite,
.f_userdump = filt_vfsdump,
+ .f_copy = filt_vfscopy,
};
static const struct filterops vfsvnode_filtops = {
.f_isfd = 1,
.f_detach = filt_vfsdetach,
.f_event = filt_vfsvnode,
.f_userdump = filt_vfsdump,
+ .f_copy = filt_vfscopy,
};
static void
@@ -6825,6 +6830,16 @@ filt_vfsdump(struct proc *p, struct knote *kn, struct kinfo_knote *kin)
return (0);
}
+static int
+filt_vfscopy(struct knote *kn, struct proc *p1)
+{
+ struct vnode *vp;
+
+ vp = (struct vnode *)kn->kn_hook;
+ vhold(vp);
+ return (0);
+}
+
int
vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off)
{
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 63a0b3260e6d..9bc743c0c6d1 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -173,6 +173,7 @@ SUBDIR= \
iflib \
${_igc} \
imgact_binmisc \
+ ${_imx} \
${_intelspi} \
${_io} \
${_ioat} \
@@ -346,6 +347,7 @@ SUBDIR= \
rc4 \
${_rdma} \
${_rdrand_rng} \
+ ${_rdseed_rng} \
re \
rl \
${_rockchip} \
@@ -680,7 +682,9 @@ _irdma= irdma
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
${MACHINE_CPUARCH} == "riscv"
.if !empty(OPT_FDT)
+_allwinner= allwinner
_if_cgem= if_cgem
+_sdhci_fdt= sdhci_fdt
.endif
.endif
@@ -713,7 +717,6 @@ _hyperv= hyperv
_vf_i2c= vf_i2c
.if !empty(OPT_FDT)
-_allwinner= allwinner
_dwwdt= dwwdt
_enetc= enetc
_felix= felix
@@ -721,12 +724,8 @@ _rockchip= rockchip
.endif
.endif
-.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
- ${MACHINE_CPUARCH} == "riscv"
-.if !empty(OPT_FDT)
-_sdhci_fdt= sdhci_fdt
-.endif
-_neta= neta
+.if ${MACHINE_CPUARCH} == "arm"
+_imx= imx
.endif
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
@@ -822,6 +821,7 @@ _nvram= nvram
_padlock= padlock
_padlock_rng= padlock_rng
_rdrand_rng= rdrand_rng
+_rdseed_rng= rdseed_rng
.endif
_pchtherm = pchtherm
_s3= s3
@@ -923,7 +923,8 @@ _nvram+= powermac_nvram
.if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "aarch64"
_bcm283x_clkman= bcm283x_clkman
-_bcm283x_pwm= bcm283x_pwm
+_bcm283x_pwm= bcm283x_pwm
+_neta= neta
.endif
.if ${MACHINE_CPUARCH} == "amd64"
diff --git a/sys/modules/allwinner/aw_sid/Makefile b/sys/modules/allwinner/aw_sid/Makefile
index 7d3dad68acb9..2679aa83d09d 100644
--- a/sys/modules/allwinner/aw_sid/Makefile
+++ b/sys/modules/allwinner/aw_sid/Makefile
@@ -7,6 +7,7 @@ SRCS+= \
bus_if.h \
clknode_if.h \
device_if.h \
- ofw_bus_if.h \
+ nvmem_if.h \
+ ofw_bus_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/allwinner/aw_thermal/Makefile b/sys/modules/allwinner/aw_thermal/Makefile
index 911e6406d947..924b09a3b3c8 100644
--- a/sys/modules/allwinner/aw_thermal/Makefile
+++ b/sys/modules/allwinner/aw_thermal/Makefile
@@ -7,6 +7,7 @@ SRCS+= \
bus_if.h \
clknode_if.h \
device_if.h \
- ofw_bus_if.h \
+ nvmem_if.h \
+ ofw_bus_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/dtb/allwinner/Makefile b/sys/modules/dtb/allwinner/Makefile
index 242ee5d974ad..2666e786a9df 100644
--- a/sys/modules/dtb/allwinner/Makefile
+++ b/sys/modules/dtb/allwinner/Makefile
@@ -65,7 +65,12 @@ DTSO= sun50i-a64-mmc0-disable.dtso \
sun50i-a64-timer.dtso \
sun50i-h5-opp.dtso \
sun50i-h5-nanopi-neo2-opp.dtso
-
+.elif ${MACHINE_CPUARCH} == "riscv"
+DTS= \
+ allwinner/sun20i-d1-dongshan-nezha-stu.dts \
+ allwinner/sun20i-d1-lichee-rv.dts \
+ allwinner/sun20i-d1-mangopi-mq-pro.dts \
+ allwinner/sun20i-d1-nezha.dts
.endif
.include <bsd.dtb.mk>
diff --git a/sys/modules/dtb/starfive/Makefile b/sys/modules/dtb/starfive/Makefile
new file mode 100644
index 000000000000..2da30f0985c7
--- /dev/null
+++ b/sys/modules/dtb/starfive/Makefile
@@ -0,0 +1,7 @@
+DTS= \
+ starfive/jh7110-pine64-star64.dts \
+ starfive/jh7110-milkv-mars.dts \
+ starfive/jh7110-starfive-visionfive-2-v1.3b.dts \
+ starfive/jh7110-starfive-visionfive-2-v1.2a.dts
+
+.include <bsd.dtb.mk>
diff --git a/sys/modules/rdrand_rng/Makefile b/sys/modules/rdrand_rng/Makefile
index 7fa7a8bb8fb9..496fc863033f 100644
--- a/sys/modules/rdrand_rng/Makefile
+++ b/sys/modules/rdrand_rng/Makefile
@@ -6,9 +6,4 @@ SRCS+= bus_if.h device_if.h
CFLAGS+= -I${SRCTOP}/sys
-# ld.bfd doesn't support ifuncs invoked non-PIC
-.if ${MACHINE_CPUARCH} == "i386"
-CFLAGS.gcc= -fPIC
-.endif
-
.include <bsd.kmod.mk>
diff --git a/sys/modules/rdseed_rng/Makefile b/sys/modules/rdseed_rng/Makefile
new file mode 100644
index 000000000000..6593505546dd
--- /dev/null
+++ b/sys/modules/rdseed_rng/Makefile
@@ -0,0 +1,9 @@
+.PATH: ${SRCTOP}/sys/dev/random
+
+KMOD= rdseed_rng
+SRCS= rdseed.c
+SRCS+= bus_if.h device_if.h
+
+CFLAGS+= -I${SRCTOP}/sys
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h
index db1b6f33a8ef..3a17ed289235 100644
--- a/sys/modules/zfs/zfs_config.h
+++ b/sys/modules/zfs/zfs_config.h
@@ -843,7 +843,7 @@
/* #undef ZFS_DEVICE_MINOR */
/* Define the project alias string. */
-#define ZFS_META_ALIAS "zfs-2.4.99-95-FreeBSD_g5605a6d79"
+#define ZFS_META_ALIAS "zfs-2.4.99-113-FreeBSD_g6ae99d269"
/* Define the project author. */
#define ZFS_META_AUTHOR "OpenZFS"
@@ -873,7 +873,7 @@
#define ZFS_META_NAME "zfs"
/* Define the project release. */
-#define ZFS_META_RELEASE "95-FreeBSD_g5605a6d79"
+#define ZFS_META_RELEASE "113-FreeBSD_g6ae99d269"
/* Define the project version. */
#define ZFS_META_VERSION "2.4.99"
diff --git a/sys/modules/zfs/zfs_gitrev.h b/sys/modules/zfs/zfs_gitrev.h
index 8a1802f5480b..6f568754f61d 100644
--- a/sys/modules/zfs/zfs_gitrev.h
+++ b/sys/modules/zfs/zfs_gitrev.h
@@ -1 +1 @@
-#define ZFS_META_GITREV "zfs-2.4.99-95-g5605a6d79"
+#define ZFS_META_GITREV "zfs-2.4.99-113-g6ae99d269"
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index a347dbe2eb73..f598733773d0 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -253,12 +253,14 @@ static const struct filterops bpfread_filtops = {
.f_isfd = 1,
.f_detach = filt_bpfdetach,
.f_event = filt_bpfread,
+ .f_copy = knote_triv_copy,
};
static const struct filterops bpfwrite_filtops = {
.f_isfd = 1,
.f_detach = filt_bpfdetach,
.f_event = filt_bpfwrite,
+ .f_copy = knote_triv_copy,
};
/*
diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c
index c8dbb6aa8893..56bb90cce9bc 100644
--- a/sys/net/if_tuntap.c
+++ b/sys/net/if_tuntap.c
@@ -261,6 +261,7 @@ static const struct filterops tun_read_filterops = {
.f_attach = NULL,
.f_detach = tunkqdetach,
.f_event = tunkqread,
+ .f_copy = knote_triv_copy,
};
static const struct filterops tun_write_filterops = {
@@ -268,6 +269,7 @@ static const struct filterops tun_write_filterops = {
.f_attach = NULL,
.f_detach = tunkqdetach,
.f_event = tunkqwrite,
+ .f_copy = knote_triv_copy,
};
static struct tuntap_driver {
diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c
index 03184c1fb678..f3a8410a2258 100644
--- a/sys/net/if_vxlan.c
+++ b/sys/net/if_vxlan.c
@@ -2533,7 +2533,7 @@ vxlan_encap4(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa,
ifp = sc->vxl_ifp;
srcaddr = sc->vxl_src_addr.in4.sin_addr;
- srcport = vxlan_pick_source_port(sc, m);
+ srcport = htons(vxlan_pick_source_port(sc, m));
dstaddr = fvxlsa->in4.sin_addr;
dstport = fvxlsa->in4.sin_port;
@@ -2644,7 +2644,7 @@ vxlan_encap6(struct vxlan_softc *sc, const union vxlan_sockaddr *fvxlsa,
ifp = sc->vxl_ifp;
srcaddr = &sc->vxl_src_addr.in6.sin6_addr;
- srcport = vxlan_pick_source_port(sc, m);
+ srcport = htons(vxlan_pick_source_port(sc, m));
dstaddr = &fvxlsa->in6.sin6_addr;
dstport = fvxlsa->in6.sin6_port;
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index dbe48242381d..712ff28768dc 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -2665,10 +2665,13 @@ in_pcbinshash(struct inpcb *inp)
INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)];
/*
- * Add entry to load balance group.
- * Only do this if SO_REUSEPORT_LB is set.
+ * Ignore SO_REUSEPORT_LB if the socket is connected. Really this case
+ * should be an error, but for UDP sockets it is not, and some
+ * applications erroneously set it on connected UDP sockets, so we can't
+ * change this without breaking compatibility.
*/
- if ((inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) {
+ if (!connected &&
+ (inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) {
int error = in_pcbinslbgrouphash(inp, M_NODOM);
if (error != 0)
return (error);
@@ -2770,6 +2773,10 @@ in_pcbrehash(struct inpcb *inp)
connected = !in_nullhost(inp->inp_faddr);
}
+ /* See the comment in in_pcbinshash(). */
+ if (connected && (inp->inp_flags & INP_INLBGROUP) != 0)
+ in_pcbremlbgrouphash(inp);
+
/*
* When rehashing, the caller must ensure that either the new or the old
* foreign address was unspecified.
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index c143d74a2f45..41f0a328daec 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -2181,7 +2181,7 @@ LibAliasInit(struct libalias *la)
#undef malloc /* XXX: ugly */
la = malloc(sizeof *la, M_ALIAS, M_WAITOK | M_ZERO);
#else
- la = calloc(sizeof *la, 1);
+ la = calloc(1, sizeof *la);
if (la == NULL)
return (la);
#endif
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index 66983edcdd73..10383bc0801e 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -477,7 +477,7 @@ bbr_log_rtt_shrinks(struct tcp_bbr *bbr, uint32_t cts, uint32_t applied,
uint16_t set);
static struct bbr_sendmap *
bbr_find_lowest_rsm(struct tcp_bbr *bbr);
-static __inline uint32_t
+static inline uint32_t
bbr_get_rtt(struct tcp_bbr *bbr, int32_t rtt_type);
static void
bbr_log_to_start(struct tcp_bbr *bbr, uint32_t cts, uint32_t to, int32_t pacing_delay,
@@ -1841,7 +1841,7 @@ bbr_counter_destroy(void)
}
-static __inline void
+static inline void
bbr_fill_in_logging_data(struct tcp_bbr *bbr, struct tcp_log_bbr *l, uint32_t cts)
{
memset(l, 0, sizeof(union tcp_log_stackspecific));
@@ -4206,7 +4206,7 @@ bbr_calc_thresh_tlp(struct tcpcb *tp, struct tcp_bbr *bbr,
/*
* Return one of three RTTs to use (in microseconds).
*/
-static __inline uint32_t
+static inline uint32_t
bbr_get_rtt(struct tcp_bbr *bbr, int32_t rtt_type)
{
uint32_t f_rtt;
@@ -4370,7 +4370,7 @@ bbr_timeout_rack(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
return (0);
}
-static __inline void
+static inline void
bbr_clone_rsm(struct tcp_bbr *bbr, struct bbr_sendmap *nrsm, struct bbr_sendmap *rsm, uint32_t start)
{
int idx;
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index c7962b57a69e..50077abdfd86 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -4730,7 +4730,7 @@ rack_make_timely_judgement(struct tcp_rack *rack, uint32_t rtt, int32_t rtt_diff
return (timely_says);
}
-static __inline int
+static inline int
rack_in_gp_window(struct tcpcb *tp, struct rack_sendmap *rsm)
{
if (SEQ_GEQ(rsm->r_start, tp->gput_seq) &&
@@ -4767,7 +4767,7 @@ rack_in_gp_window(struct tcpcb *tp, struct rack_sendmap *rsm)
return (0);
}
-static __inline void
+static inline void
rack_mark_in_gp_win(struct tcpcb *tp, struct rack_sendmap *rsm)
{
@@ -4784,7 +4784,7 @@ rack_mark_in_gp_win(struct tcpcb *tp, struct rack_sendmap *rsm)
rsm->r_flags &= ~RACK_IN_GP_WIN;
}
-static __inline void
+static inline void
rack_clear_gp_marks(struct tcpcb *tp, struct tcp_rack *rack)
{
/* A GP measurement is ending, clear all marks on the send map*/
@@ -4802,7 +4802,7 @@ rack_clear_gp_marks(struct tcpcb *tp, struct tcp_rack *rack)
}
-static __inline void
+static inline void
rack_tend_gp_marks(struct tcpcb *tp, struct tcp_rack *rack)
{
struct rack_sendmap *rsm = NULL;
@@ -6864,6 +6864,18 @@ rack_mark_lost(struct tcpcb *tp,
}
}
+static inline void
+rack_mark_nolonger_lost(struct tcp_rack *rack, struct rack_sendmap *rsm)
+{
+ KASSERT((rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)),
+ ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
+ rsm->r_flags &= ~RACK_WAS_LOST;
+ if (rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start))
+ rack->r_ctl.rc_considered_lost -= rsm->r_end - rsm->r_start;
+ else
+ rack->r_ctl.rc_considered_lost = 0;
+}
+
/*
* RACK Timer, here we simply do logging and house keeping.
* the normal rack_output() function will call the
@@ -7005,7 +7017,7 @@ rack_setup_offset_for_rsm(struct tcp_rack *rack, struct rack_sendmap *src_rsm, s
rsm->orig_t_space = M_TRAILINGROOM(rsm->m);
}
-static __inline void
+static inline void
rack_clone_rsm(struct tcp_rack *rack, struct rack_sendmap *nrsm,
struct rack_sendmap *rsm, uint32_t start)
{
@@ -8130,13 +8142,7 @@ rack_update_rsm(struct tcpcb *tp, struct tcp_rack *rack,
* remove the lost desgination and reduce the
* bytes considered lost.
*/
- rsm->r_flags &= ~RACK_WAS_LOST;
- KASSERT((rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)),
- ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
- if (rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start))
- rack->r_ctl.rc_considered_lost -= rsm->r_end - rsm->r_start;
- else
- rack->r_ctl.rc_considered_lost = 0;
+ rack_mark_nolonger_lost(rack, rsm);
}
idx = rsm->r_rtr_cnt - 1;
rsm->r_tim_lastsent[idx] = ts;
@@ -9492,6 +9498,11 @@ do_rest_ofb:
if (rsm->r_flags & RACK_WAS_LOST) {
int my_chg;
+ /*
+ * Note here we do not use our rack_mark_nolonger_lost() function
+ * since we are moving our data pointer around and the
+ * ack'ed side is already not considered lost.
+ */
my_chg = (nrsm->r_end - nrsm->r_start);
KASSERT((rack->r_ctl.rc_considered_lost >= my_chg),
("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
@@ -9659,16 +9670,11 @@ do_rest_ofb:
changed += (rsm->r_end - rsm->r_start);
/* You get a count for acking a whole segment or more */
if (rsm->r_flags & RACK_WAS_LOST) {
- int my_chg;
-
- my_chg = (rsm->r_end - rsm->r_start);
- rsm->r_flags &= ~RACK_WAS_LOST;
- KASSERT((rack->r_ctl.rc_considered_lost >= my_chg),
- ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
- if (my_chg <= rack->r_ctl.rc_considered_lost)
- rack->r_ctl.rc_considered_lost -= my_chg;
- else
- rack->r_ctl.rc_considered_lost = 0;
+ /*
+ * Here we can use the inline function since
+ * the rsm is truly marked lost and now no longer lost.
+ */
+ rack_mark_nolonger_lost(rack, rsm);
}
rack->r_ctl.rc_sacked += (rsm->r_end - rsm->r_start);
if (rsm->r_in_tmap) /* should be true */
@@ -9851,6 +9857,10 @@ do_rest_ofb:
if (rsm->r_flags & RACK_WAS_LOST) {
int my_chg;
+ /*
+ * Note here we are using hookery again so we can't
+ * use our rack_mark_nolonger_lost() function.
+ */
my_chg = (nrsm->r_end - nrsm->r_start);
KASSERT((rack->r_ctl.rc_considered_lost >= my_chg),
("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
@@ -9952,16 +9962,10 @@ do_rest_ofb:
rack_update_rtt(tp, rack, rsm, to, cts, SACKED, 0);
changed += (rsm->r_end - rsm->r_start);
if (rsm->r_flags & RACK_WAS_LOST) {
- int my_chg;
-
- my_chg = (rsm->r_end - rsm->r_start);
- rsm->r_flags &= ~RACK_WAS_LOST;
- KASSERT((rack->r_ctl.rc_considered_lost >= my_chg),
- ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
- if (my_chg <= rack->r_ctl.rc_considered_lost)
- rack->r_ctl.rc_considered_lost -= my_chg;
- else
- rack->r_ctl.rc_considered_lost = 0;
+ /*
+ * Here it is safe to use our function.
+ */
+ rack_mark_nolonger_lost(rack, rsm);
}
rack->r_ctl.rc_sacked += (rsm->r_end - rsm->r_start);
@@ -10362,13 +10366,7 @@ more:
* and yet before retransmitting we get an ack
* which can happen due to reordering.
*/
- rsm->r_flags &= ~RACK_WAS_LOST;
- KASSERT((rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)),
- ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack));
- if (rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start))
- rack->r_ctl.rc_considered_lost -= rsm->r_end - rsm->r_start;
- else
- rack->r_ctl.rc_considered_lost = 0;
+ rack_mark_nolonger_lost(rack, rsm);
}
rack_log_map_chg(tp, rack, NULL, rsm, NULL, MAP_FREE, rsm->r_end, __LINE__);
rack->r_ctl.rc_holes_rxt -= rsm->r_rtr_bytes;
@@ -10476,12 +10474,7 @@ more:
* which can happen due to reordering. In this
* case its only a partial ack of the send.
*/
- KASSERT((rack->r_ctl.rc_considered_lost >= (th_ack - rsm->r_start)),
- ("rsm:%p rack:%p rc_considered_lost goes negative th_ack:%u", rsm, rack, th_ack));
- if (rack->r_ctl.rc_considered_lost >= (th_ack - rsm->r_start))
- rack->r_ctl.rc_considered_lost -= th_ack - rsm->r_start;
- else
- rack->r_ctl.rc_considered_lost = 0;
+ rack_mark_nolonger_lost(rack, rsm);
}
/*
* Clear the dup ack count for
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index be20fb44a820..3cb538f7054d 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1168,7 +1168,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
/*
* If listening socket requested TCP digests, check that
* received ACK has signature and it is correct.
- * If not, drop the ACK and leave sc entry in th cache,
+ * If not, drop the ACK and leave sc entry in the cache,
* because SYN was received with correct signature.
*/
if (sc->sc_flags & SCF_SIGNATURE) {
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index cea8a916679b..0a89d91dfc37 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -787,7 +787,8 @@ udplite_ctlinput(struct icmp *icmp)
static int
udp_pcblist(SYSCTL_HANDLER_ARGS)
{
- struct inpcb_iterator inpi = INP_ALL_ITERATOR(&V_udbinfo,
+ struct inpcbinfo *pcbinfo = udp_get_inpcbinfo(arg2);
+ struct inpcb_iterator inpi = INP_ALL_ITERATOR(pcbinfo,
INPLOOKUP_RLOCKPCB);
struct xinpgen xig;
struct inpcb *inp;
@@ -799,7 +800,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
if (req->oldptr == 0) {
int n;
- n = V_udbinfo.ipi_count;
+ n = pcbinfo->ipi_count;
n += imax(n / 8, 10);
req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xinpcb);
return (0);
@@ -810,8 +811,8 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
bzero(&xig, sizeof(xig));
xig.xig_len = sizeof xig;
- xig.xig_count = V_udbinfo.ipi_count;
- xig.xig_gen = V_udbinfo.ipi_gencnt;
+ xig.xig_count = pcbinfo->ipi_count;
+ xig.xig_gen = pcbinfo->ipi_gencnt;
xig.xig_sogen = so_gencnt;
error = SYSCTL_OUT(req, &xig, sizeof xig);
if (error)
@@ -838,9 +839,9 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
* that something happened while we were processing this
* request, and it might be necessary to retry.
*/
- xig.xig_gen = V_udbinfo.ipi_gencnt;
+ xig.xig_gen = pcbinfo->ipi_gencnt;
xig.xig_sogen = so_gencnt;
- xig.xig_count = V_udbinfo.ipi_count;
+ xig.xig_count = pcbinfo->ipi_count;
error = SYSCTL_OUT(req, &xig, sizeof xig);
}
@@ -848,7 +849,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
}
SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist,
- CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+ CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, IPPROTO_UDP,
udp_pcblist, "S,xinpcb",
"List of active UDP sockets");
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index d6fc24a23fe9..fd70fb1c8a36 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -5965,6 +5965,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
ctx.nat_pool = &(ctx.nr->rdr);
}
+ *ctx.rm = &V_pf_default_rule;
if (ctx.nr && ctx.nr->natpass) {
r = ctx.nr;
ruleset = *ctx.rsm;
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index fb1b121d0bc0..5d85e16f18e3 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -216,6 +216,7 @@ pf_match_translation_rule(int rs_num, struct pf_test_ctx *ctx, struct pf_krulese
*/
ctx->arsm = ctx->aruleset;
}
+ break;
} else {
ctx->a = r; /* remember anchor */
ctx->aruleset = ruleset; /* and its ruleset */
diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c
index e1118713bff0..6b904c02ea15 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -143,7 +143,7 @@ struct sysentvec elf32_freebsd_sysvec = {
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
-static Elf32_Brandinfo freebsd_brand_info = {
+static const Elf32_Brandinfo freebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_PPC,
.compat_3_brand = "FreeBSD",
@@ -158,11 +158,11 @@ static Elf32_Brandinfo freebsd_brand_info = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
+C_SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info);
-static Elf32_Brandinfo freebsd_brand_oinfo = {
+static const Elf32_Brandinfo freebsd_brand_oinfo = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_PPC,
.compat_3_brand = "FreeBSD",
@@ -173,7 +173,7 @@ static Elf32_Brandinfo freebsd_brand_oinfo = {
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
+C_SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_oinfo);
diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c
index a999f742caeb..0be40bed69cb 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -154,7 +154,7 @@ static bool ppc64_elfv1_header_match(const struct image_params *params,
static bool ppc64_elfv2_header_match(const struct image_params *params,
const int32_t *, const uint32_t *);
-static Elf64_Brandinfo freebsd_brand_info_elfv1 = {
+static const Elf64_Brandinfo freebsd_brand_info_elfv1 = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_PPC64,
.compat_3_brand = "FreeBSD",
@@ -166,11 +166,11 @@ static Elf64_Brandinfo freebsd_brand_info_elfv1 = {
.header_supported = &ppc64_elfv1_header_match
};
-SYSINIT(elf64v1, SI_SUB_EXEC, SI_ORDER_ANY,
+C_SYSINIT(elf64v1, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info_elfv1);
-static Elf64_Brandinfo freebsd_brand_info_elfv2 = {
+static const Elf64_Brandinfo freebsd_brand_info_elfv2 = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_PPC64,
.compat_3_brand = "FreeBSD",
@@ -182,11 +182,11 @@ static Elf64_Brandinfo freebsd_brand_info_elfv2 = {
.header_supported = &ppc64_elfv2_header_match
};
-SYSINIT(elf64v2, SI_SUB_EXEC, SI_ORDER_ANY,
+C_SYSINIT(elf64v2, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info_elfv2);
-static Elf64_Brandinfo freebsd_brand_oinfo = {
+static const Elf64_Brandinfo freebsd_brand_oinfo = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_PPC64,
.compat_3_brand = "FreeBSD",
@@ -198,7 +198,7 @@ static Elf64_Brandinfo freebsd_brand_oinfo = {
.header_supported = &ppc64_elfv1_header_match
};
-SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
+C_SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_oinfo);
diff --git a/sys/riscv/conf/std.allwinner b/sys/riscv/conf/std.allwinner
index 34fe195b01ba..ecd789f39963 100644
--- a/sys/riscv/conf/std.allwinner
+++ b/sys/riscv/conf/std.allwinner
@@ -17,4 +17,7 @@ device awg # Allwinner EMAC Gigabit Ethernet
device musb # Mentor Graphics USB OTG controller
+# DTBs
+makeoptions MODULES_EXTRA+="dtb/allwinner"
+
files "../allwinner/files.allwinner"
diff --git a/sys/riscv/conf/std.starfive b/sys/riscv/conf/std.starfive
index 9bdb1af9e79c..6a0e56cc84bd 100644
--- a/sys/riscv/conf/std.starfive
+++ b/sys/riscv/conf/std.starfive
@@ -10,4 +10,7 @@ device eqos
device dwmmc
device dwmmc_starfive
+# DTBs
+makeoptions MODULES_EXTRA+="dtb/starfive"
+
files "../starfive/files.starfive"
diff --git a/sys/riscv/riscv/elf_machdep.c b/sys/riscv/riscv/elf_machdep.c
index 67b1fcc4c1a9..5bd4af4c15f8 100644
--- a/sys/riscv/riscv/elf_machdep.c
+++ b/sys/riscv/riscv/elf_machdep.c
@@ -100,7 +100,7 @@ static struct sysentvec elf64_freebsd_sysvec = {
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
-static Elf64_Brandinfo freebsd_brand_info = {
+static const Elf64_Brandinfo freebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_RISCV,
.compat_3_brand = "FreeBSD",
@@ -110,7 +110,7 @@ static Elf64_Brandinfo freebsd_brand_info = {
.brand_note = &elf64_freebsd_brandnote,
.flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
};
-SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST,
+C_SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST,
(sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info);
static void
diff --git a/sys/riscv/vmm/vmm.c b/sys/riscv/vmm/vmm.c
index 4c9b1fa53f7a..24b4be89af48 100644
--- a/sys/riscv/vmm/vmm.c
+++ b/sys/riscv/vmm/vmm.c
@@ -954,8 +954,7 @@ vcpu_get_state(struct vcpu *vcpu, int *hostcpu)
int
vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval)
{
-
- if (reg >= VM_REG_LAST)
+ if (reg < 0 || reg >= VM_REG_LAST)
return (EINVAL);
return (vmmops_getreg(vcpu->cookie, reg, retval));
@@ -966,7 +965,7 @@ vm_set_register(struct vcpu *vcpu, int reg, uint64_t val)
{
int error;
- if (reg >= VM_REG_LAST)
+ if (reg < 0 || reg >= VM_REG_LAST)
return (EINVAL);
error = vmmops_setreg(vcpu->cookie, reg, val);
if (error || reg != VM_REG_GUEST_SEPC)
diff --git a/sys/riscv/vmm/vmm_dev_machdep.c b/sys/riscv/vmm/vmm_dev_machdep.c
index ba15d8dcd79e..c736b10dc9c0 100644
--- a/sys/riscv/vmm/vmm_dev_machdep.c
+++ b/sys/riscv/vmm/vmm_dev_machdep.c
@@ -67,18 +67,13 @@ int
vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
int fflag, struct thread *td)
{
- struct vm_run *vmrun;
- struct vm_aplic_descr *aplic;
- struct vm_irq *vi;
- struct vm_exception *vmexc;
- struct vm_gla2gpa *gg;
- struct vm_msi *vmsi;
int error;
error = 0;
switch (cmd) {
case VM_RUN: {
struct vm_exit *vme;
+ struct vm_run *vmrun;
vmrun = (struct vm_run *)data;
vme = vm_exitinfo(vcpu);
@@ -90,34 +85,52 @@ vmmdev_machdep_ioctl(struct vm *vm, struct vcpu *vcpu, u_long cmd, caddr_t data,
error = copyout(vme, vmrun->vm_exit, sizeof(*vme));
break;
}
- case VM_INJECT_EXCEPTION:
+ case VM_INJECT_EXCEPTION: {
+ struct vm_exception *vmexc;
+
vmexc = (struct vm_exception *)data;
error = vm_inject_exception(vcpu, vmexc->scause);
break;
- case VM_GLA2GPA_NOFAULT:
+ }
+ case VM_GLA2GPA_NOFAULT: {
+ struct vm_gla2gpa *gg;
+
gg = (struct vm_gla2gpa *)data;
error = vm_gla2gpa_nofault(vcpu, &gg->paging, gg->gla,
gg->prot, &gg->gpa, &gg->fault);
KASSERT(error == 0 || error == EFAULT,
("%s: vm_gla2gpa unknown error %d", __func__, error));
break;
- case VM_ATTACH_APLIC:
+ }
+ case VM_ATTACH_APLIC: {
+ struct vm_aplic_descr *aplic;
+
aplic = (struct vm_aplic_descr *)data;
error = vm_attach_aplic(vm, aplic);
break;
- case VM_RAISE_MSI:
+ }
+ case VM_RAISE_MSI: {
+ struct vm_msi *vmsi;
+
vmsi = (struct vm_msi *)data;
error = vm_raise_msi(vm, vmsi->msg, vmsi->addr, vmsi->bus,
vmsi->slot, vmsi->func);
break;
- case VM_ASSERT_IRQ:
+ }
+ case VM_ASSERT_IRQ: {
+ struct vm_irq *vi;
+
vi = (struct vm_irq *)data;
error = vm_assert_irq(vm, vi->irq);
break;
- case VM_DEASSERT_IRQ:
+ }
+ case VM_DEASSERT_IRQ: {
+ struct vm_irq *vi;
+
vi = (struct vm_irq *)data;
error = vm_deassert_irq(vm, vi->irq);
break;
+ }
default:
error = ENOTTY;
break;
diff --git a/sys/security/audit/audit_pipe.c b/sys/security/audit/audit_pipe.c
index fb773fd04297..4d9815467e1a 100644
--- a/sys/security/audit/audit_pipe.c
+++ b/sys/security/audit/audit_pipe.c
@@ -243,6 +243,7 @@ static const struct filterops audit_pipe_read_filterops = {
.f_attach = NULL,
.f_detach = audit_pipe_kqdetach,
.f_event = audit_pipe_kqread,
+ .f_copy = knote_triv_copy,
};
/*
diff --git a/sys/sys/ata.h b/sys/sys/ata.h
index 5e9c2bcb9aa0..9ce822214f6d 100644
--- a/sys/sys/ata.h
+++ b/sys/sys/ata.h
@@ -347,8 +347,11 @@ struct ata_params {
#define ATA_STATUS_BUSY 0x80
/* ATA Error Register */
+/* COMMAND TIMEOUT 0x01 */
#define ATA_ERROR_ABORT 0x04
#define ATA_ERROR_ID_NOT_FOUND 0x10
+/* UNCORRECTABLE ERROR 0x40 */
+/* INTERFACE CRC 0x80 */
/* ATA HPA Features */
#define ATA_HPA_FEAT_MAX_ADDR 0x00
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 084eaafcbdc0..ebbcdb703183 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -228,6 +228,7 @@ struct freebsd11_kevent32 {
/* Flags for kqueuex(2) */
#define KQUEUE_CLOEXEC 0x00000001 /* close on exec */
+#define KQUEUE_CPONFORK 0x00000002 /* copy on fork */
struct knote;
SLIST_HEAD(klist, knote);
@@ -283,6 +284,7 @@ struct filterops {
void (*f_touch)(struct knote *kn, struct kevent *kev, u_long type);
int (*f_userdump)(struct proc *p, struct knote *kn,
struct kinfo_knote *kin);
+ int (*f_copy)(struct knote *kn, struct proc *p1);
};
/*
@@ -346,6 +348,7 @@ struct rwlock;
void knote(struct knlist *list, long hint, int lockflags);
void knote_fork(struct knlist *list, int pid);
+int knote_triv_copy(struct knote *kn, struct proc *p1);
struct knlist *knlist_alloc(struct mtx *lock);
void knlist_detach(struct knlist *knl);
void knlist_add(struct knlist *knl, struct knote *kn, int islocked);
diff --git a/sys/sys/eventvar.h b/sys/sys/eventvar.h
index 7fec444447f9..7cb3269f1fdf 100644
--- a/sys/sys/eventvar.h
+++ b/sys/sys/eventvar.h
@@ -55,12 +55,14 @@ struct kqueue {
#define KQ_CLOSING 0x10
#define KQ_TASKSCHED 0x20 /* task scheduled */
#define KQ_TASKDRAIN 0x40 /* waiting for task to drain */
+#define KQ_CPONFORK 0x80
int kq_knlistsize; /* size of knlist */
struct klist *kq_knlist; /* list of knotes */
u_long kq_knhashmask; /* size of knhash */
struct klist *kq_knhash; /* hash table for knotes */
struct task kq_task;
struct ucred *kq_cred;
+ struct kqueue *kq_forksrc;
};
#endif /* !_SYS_EVENTVAR_H_ */
diff --git a/sys/sys/file.h b/sys/sys/file.h
index c44fd0f28929..e0195c7c6c2a 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -139,6 +139,8 @@ typedef int fo_fspacectl_t(struct file *fp, int cmd,
off_t *offset, off_t *length, int flags,
struct ucred *active_cred, struct thread *td);
typedef int fo_cmp_t(struct file *fp, struct file *fp1, struct thread *td);
+typedef int fo_fork_t(struct filedesc *fdp, struct file *fp, struct file **fp1,
+ struct proc *p1, struct thread *td);
typedef int fo_spare_t(struct file *fp);
typedef int fo_flags_t;
@@ -163,12 +165,14 @@ struct fileops {
fo_fallocate_t *fo_fallocate;
fo_fspacectl_t *fo_fspacectl;
fo_cmp_t *fo_cmp;
+ fo_fork_t *fo_fork;
fo_spare_t *fo_spares[8]; /* Spare slots */
fo_flags_t fo_flags; /* DFLAG_* below */
};
#define DFLAG_PASSABLE 0x01 /* may be passed via unix sockets. */
#define DFLAG_SEEKABLE 0x02 /* seekable / nonsequential */
+#define DFLAG_FORK 0x04 /* copy on fork */
#endif /* _KERNEL */
#if defined(_KERNEL) || defined(_WANT_FILE)
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 0a388c90de26..4817855443af 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -265,7 +265,7 @@ int fdcheckstd(struct thread *td);
void fdclose(struct thread *td, struct file *fp, int idx);
void fdcloseexec(struct thread *td);
void fdsetugidsafety(struct thread *td);
-struct filedesc *fdcopy(struct filedesc *fdp);
+struct filedesc *fdcopy(struct filedesc *fdp, struct proc *p1);
void fdunshare(struct thread *td);
void fdescfree(struct thread *td);
int fdlastfile(struct filedesc *fdp);
diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h
index 9e2a233248b4..25ce7871ba7c 100644
--- a/sys/sys/imgact_elf.h
+++ b/sys/sys/imgact_elf.h
@@ -87,7 +87,7 @@ typedef struct {
const char *interp_newpath;
int flags;
const Elf_Brandnote *brand_note;
- bool (*header_supported)(const struct image_params *,
+ bool (*const header_supported)(const struct image_params *,
const int32_t *, const uint32_t *);
/* High 8 bits of flags is private to the ABI */
#define BI_CAN_EXEC_DYN 0x0001
@@ -132,8 +132,8 @@ bool __elfN(parse_notes)(const struct image_params *, const Elf_Note *,
void __elfN(dump_thread)(struct thread *, void *, size_t *);
extern int __elfN(fallback_brand);
-extern Elf_Brandnote __elfN(freebsd_brandnote);
-extern Elf_Brandnote __elfN(kfreebsd_brandnote);
+extern const Elf_Brandnote __elfN(freebsd_brandnote);
+extern const Elf_Brandnote __elfN(kfreebsd_brandnote);
#endif /* _KERNEL */
#endif /* !_SYS_IMGACT_ELF_H_ */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 8a71693cff3d..7cfa3c6aa4a8 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -74,7 +74,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1600001
+#define __FreeBSD_version 1600002
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/random.h b/sys/sys/random.h
index 2a68f0c99b6d..af6b1e117423 100644
--- a/sys/sys/random.h
+++ b/sys/sys/random.h
@@ -89,11 +89,11 @@ enum random_entropy_source {
RANDOM_ENVIRONMENTAL_END = RANDOM_RANDOMDEV,
/* Fast hardware random-number sources from here on. */
RANDOM_PURE_START,
- RANDOM_PURE_OCTEON = RANDOM_PURE_START,
- RANDOM_PURE_SAFE,
+ RANDOM_PURE_SAFE = RANDOM_PURE_START,
RANDOM_PURE_GLXSB,
RANDOM_PURE_HIFN,
RANDOM_PURE_RDRAND,
+ RANDOM_PURE_RDSEED,
RANDOM_PURE_NEHEMIAH,
RANDOM_PURE_RNDTEST,
RANDOM_PURE_VIRTIO,
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 8237165b84ce..d32690634059 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -211,7 +211,8 @@ int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges,
int nevents, struct kevent_copyops *k_ops,
const struct timespec *timeout);
int kern_kill(struct thread *td, pid_t pid, int signum);
-int kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps);
+int kern_kqueue(struct thread *td, int flags, bool cponfork,
+ struct filecaps *fcaps);
int kern_kldload(struct thread *td, const char *file, int *fileid);
int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat);
int kern_kldunload(struct thread *td, int fileid, int flags);
diff --git a/sys/x86/acpica/acpi_apm.c b/sys/x86/acpica/acpi_apm.c
index 8e5785cf0ed6..919f76949dd4 100644
--- a/sys/x86/acpica/acpi_apm.c
+++ b/sys/x86/acpica/acpi_apm.c
@@ -64,6 +64,7 @@ static const struct filterops apm_readfiltops = {
.f_isfd = 1,
.f_detach = apmreadfiltdetach,
.f_event = apmreadfilt,
+ .f_copy = knote_triv_copy,
};
static struct cdevsw apm_cdevsw = {
diff --git a/sys/x86/iommu/amd_intrmap.c b/sys/x86/iommu/amd_intrmap.c
index f8900fe0561f..cce4f57ca323 100644
--- a/sys/x86/iommu/amd_intrmap.c
+++ b/sys/x86/iommu/amd_intrmap.c
@@ -223,9 +223,9 @@ static struct amdiommu_ctx *
amdiommu_ir_find(device_t src, uint16_t *ridp, bool *is_iommu)
{
devclass_t src_class;
- device_t requester;
struct amdiommu_unit *unit;
struct amdiommu_ctx *ctx;
+ struct iommu_ctx *ioctx;
uint32_t edte;
uint16_t rid;
uint8_t dte;
@@ -255,10 +255,9 @@ amdiommu_ir_find(device_t src, uint16_t *ridp, bool *is_iommu)
error = amdiommu_find_unit(src, &unit, &rid, &dte, &edte,
bootverbose);
if (error == 0) {
- error = iommu_get_requester(src, &requester, &rid);
- MPASS(error == 0);
- ctx = amdiommu_get_ctx_for_dev(unit, src,
- rid, 0, false /* XXXKIB */, false, dte, edte);
+ ioctx = iommu_instantiate_ctx(AMD2IOMMU(unit), src, false);
+ if (ioctx != NULL)
+ ctx = IOCTX2CTX(ioctx);
}
}
if (ridp != NULL)
diff --git a/tests/sys/geom/class/Makefile b/tests/sys/geom/class/Makefile
index 3cf3a15273ac..c58ebc0f72a0 100644
--- a/tests/sys/geom/class/Makefile
+++ b/tests/sys/geom/class/Makefile
@@ -9,6 +9,7 @@ TESTS_SUBDIRS+= concat
TESTS_SUBDIRS+= eli
.endif
TESTS_SUBDIRS+= gate
+TESTS_SUBDIRS+= label
TESTS_SUBDIRS+= mirror
TESTS_SUBDIRS+= multipath
TESTS_SUBDIRS+= nop
diff --git a/tests/sys/geom/class/label/Makefile b/tests/sys/geom/class/label/Makefile
new file mode 100644
index 000000000000..d0072a52c47c
--- /dev/null
+++ b/tests/sys/geom/class/label/Makefile
@@ -0,0 +1,7 @@
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+ATF_TESTS_SH+= basic
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/label/basic.sh b/tests/sys/geom/class/label/basic.sh
new file mode 100755
index 000000000000..b67b41567c02
--- /dev/null
+++ b/tests/sys/geom/class/label/basic.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2025 Brad Davis
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+class=label
+. $(atf_get_srcdir)/../geom_subr.sh
+
+atf_test_case create cleanup
+create_head()
+{
+ atf_set "descr" "Create and verify GEOM labels"
+ atf_set "require.user" "root"
+}
+create_body()
+{
+ geom_atf_test_setup
+
+ f1=$(mktemp ${class}.XXXXXX)
+ atf_check truncate -s 32M "$f1"
+ attach_md md -t vnode -f "$f1"
+
+ atf_check -s exit:0 -o match:"^Done." glabel create -v test "/dev/$md"
+ atf_check -s exit:0 -o match:"^label/test N/A $md$" glabel status "/dev/$md"
+ atf_check -s exit:0 -o match:"^/dev/label/test$" ls /dev/label/test
+ atf_check -s exit:0 glabel stop test
+}
+create_cleanup()
+{
+ geom_test_cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case create
+}
diff --git a/tests/sys/netinet/so_reuseport_lb_test.c b/tests/sys/netinet/so_reuseport_lb_test.c
index 0479bd070ca6..393a626af5a4 100644
--- a/tests/sys/netinet/so_reuseport_lb_test.c
+++ b/tests/sys/netinet/so_reuseport_lb_test.c
@@ -29,6 +29,8 @@
#include <sys/param.h>
#include <sys/event.h>
+#include <sys/filio.h>
+#include <sys/ioccom.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -556,6 +558,150 @@ ATF_TC_BODY(connect_bound, tc)
close(s);
}
+/*
+ * The kernel erroneously permits calling connect() on a UDP socket with
+ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are
+ * dropped unless they come from the connected address.
+ */
+ATF_TC_WITHOUT_HEAD(connect_udp);
+ATF_TC_BODY(connect_udp, tc)
+{
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_len = sizeof(sin),
+ .sin_addr = { htonl(INADDR_LOOPBACK) },
+ };
+ ssize_t n;
+ int error, len, s1, s2, s3;
+ char ch;
+
+ s1 = socket(PF_INET, SOCK_DGRAM, 0);
+ ATF_REQUIRE(s1 >= 0);
+ s2 = socket(PF_INET, SOCK_DGRAM, 0);
+ ATF_REQUIRE(s2 >= 0);
+ s3 = socket(PF_INET, SOCK_DGRAM, 0);
+ ATF_REQUIRE(s3 >= 0);
+
+ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1},
+ sizeof(int));
+ ATF_REQUIRE_MSG(error == 0,
+ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno));
+ error = bind(s1, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno));
+
+ error = bind(s2, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno));
+
+ error = bind(s3, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno));
+
+ /* Connect to an address not owned by s2. */
+ error = getsockname(s3, (struct sockaddr *)&sin,
+ (socklen_t[]){sizeof(sin)});
+ ATF_REQUIRE(error == 0);
+ error = connect(s1, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno));
+
+ /* Try to send a packet to s1 from s2. */
+ error = getsockname(s1, (struct sockaddr *)&sin,
+ (socklen_t[]){sizeof(sin)});
+ ATF_REQUIRE(error == 0);
+
+ ch = 42;
+ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin,
+ sizeof(sin));
+ ATF_REQUIRE(n == 1);
+
+ /* Give the packet some time to arrive. */
+ usleep(100000);
+
+ /* s1 is connected to s3 and shouldn't receive from s2. */
+ error = ioctl(s1, FIONREAD, &len);
+ ATF_REQUIRE(error == 0);
+ ATF_REQUIRE_MSG(len == 0, "unexpected data available");
+
+ /* ... but s3 can of course send to s1. */
+ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin,
+ sizeof(sin));
+ ATF_REQUIRE(n == 1);
+ usleep(100000);
+ error = ioctl(s1, FIONREAD, &len);
+ ATF_REQUIRE(error == 0);
+ ATF_REQUIRE_MSG(len == 1, "expected data available");
+}
+
+/*
+ * The kernel erroneously permits calling connect() on a UDP socket with
+ * SO_REUSEPORT_LB set. Verify that packets sent to the bound address are
+ * dropped unless they come from the connected address.
+ */
+ATF_TC_WITHOUT_HEAD(connect_udp6);
+ATF_TC_BODY(connect_udp6, tc)
+{
+ struct sockaddr_in6 sin6 = {
+ .sin6_family = AF_INET6,
+ .sin6_len = sizeof(sin6),
+ .sin6_addr = IN6ADDR_LOOPBACK_INIT,
+ };
+ ssize_t n;
+ int error, len, s1, s2, s3;
+ char ch;
+
+ s1 = socket(PF_INET6, SOCK_DGRAM, 0);
+ ATF_REQUIRE(s1 >= 0);
+ s2 = socket(PF_INET6, SOCK_DGRAM, 0);
+ ATF_REQUIRE(s2 >= 0);
+ s3 = socket(PF_INET6, SOCK_DGRAM, 0);
+ ATF_REQUIRE(s3 >= 0);
+
+ error = setsockopt(s1, SOL_SOCKET, SO_REUSEPORT_LB, (int[]){1},
+ sizeof(int));
+ ATF_REQUIRE_MSG(error == 0,
+ "setsockopt(SO_REUSEPORT_LB) failed: %s", strerror(errno));
+ error = bind(s1, (struct sockaddr *)&sin6, sizeof(sin6));
+ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno));
+
+ error = bind(s2, (struct sockaddr *)&sin6, sizeof(sin6));
+ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno));
+
+ error = bind(s3, (struct sockaddr *)&sin6, sizeof(sin6));
+ ATF_REQUIRE_MSG(error == 0, "bind() failed: %s", strerror(errno));
+
+ /* Connect to an address not owned by s2. */
+ error = getsockname(s3, (struct sockaddr *)&sin6,
+ (socklen_t[]){sizeof(sin6)});
+ ATF_REQUIRE(error == 0);
+ error = connect(s1, (struct sockaddr *)&sin6, sizeof(sin6));
+ ATF_REQUIRE_MSG(error == 0, "connect() failed: %s", strerror(errno));
+
+ /* Try to send a packet to s1 from s2. */
+ error = getsockname(s1, (struct sockaddr *)&sin6,
+ (socklen_t[]){sizeof(sin6)});
+ ATF_REQUIRE(error == 0);
+
+ ch = 42;
+ n = sendto(s2, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6,
+ sizeof(sin6));
+ ATF_REQUIRE(n == 1);
+
+ /* Give the packet some time to arrive. */
+ usleep(100000);
+
+ /* s1 is connected to s3 and shouldn't receive from s2. */
+ error = ioctl(s1, FIONREAD, &len);
+ ATF_REQUIRE(error == 0);
+ ATF_REQUIRE_MSG(len == 0, "unexpected data available");
+
+ /* ... but s3 can of course send to s1. */
+ n = sendto(s3, &ch, sizeof(ch), 0, (struct sockaddr *)&sin6,
+ sizeof(sin6));
+ ATF_REQUIRE(n == 1);
+ usleep(100000);
+ error = ioctl(s1, FIONREAD, &len);
+ ATF_REQUIRE(error == 0);
+ ATF_REQUIRE_MSG(len == 1, "expected data available");
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, basic_ipv4);
@@ -566,6 +712,8 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, bind_without_listen);
ATF_TP_ADD_TC(tp, connect_not_bound);
ATF_TP_ADD_TC(tp, connect_bound);
+ ATF_TP_ADD_TC(tp, connect_udp);
+ ATF_TP_ADD_TC(tp, connect_udp6);
return (atf_no_error());
}
diff --git a/tests/sys/netpfil/pf/rdr.sh b/tests/sys/netpfil/pf/rdr.sh
index 24b95b2047f4..b0f0e6d13d0f 100644
--- a/tests/sys/netpfil/pf/rdr.sh
+++ b/tests/sys/netpfil/pf/rdr.sh
@@ -338,6 +338,56 @@ natpass_cleanup()
pft_cleanup
}
+atf_test_case "pr290177" "cleanup"
+pr290177_head()
+{
+ atf_set descr 'Test PR290177'
+ atf_set require.user root
+}
+
+pr290177_body()
+{
+ pft_init
+
+ epair=$(vnet_mkepair)
+
+ ifconfig ${epair}a 192.0.2.2/24 up
+ ifconfig ${epair}a inet alias 192.0.2.3/24 up
+
+ vnet_mkjail alcatraz ${epair}b
+ jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up
+ jexec alcatraz ifconfig lo0 127.0.0.1/8 up
+
+ # Sanity check
+ atf_check -s exit:0 -o ignore \
+ ping -c 1 192.0.2.1
+
+ jexec alcatraz pfctl -e
+ pft_set_rules alcatraz \
+ "table <white> { 192.0.2.2 }" \
+ "no rdr inet proto tcp from <white> to any port 25" \
+ "rdr pass inet proto tcp from any to any port 25 -> 127.0.0.1 port 2500"
+
+ echo foo | jexec alcatraz nc -N -l 2500 &
+ sleep 1
+
+ reply=$(nc -w 3 -s 192.0.2.2 192.0.2.1 25)
+ if [ "${reply}" == "foo" ]
+ then
+ atf_fail "no rdr rule failed"
+ fi
+ reply=$(nc -w 3 -s 192.0.2.3 192.0.2.1 25)
+ if [ "${reply}" != "foo" ]
+ then
+ atf_fail "rdr rule failed"
+ fi
+}
+
+pr290177_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "natpass"
@@ -345,4 +395,5 @@ atf_init_test_cases()
atf_add_test_case "tcp_v6_pass"
atf_add_test_case "srcport_compat"
atf_add_test_case "srcport_pass"
+ atf_add_test_case "pr290177"
}
diff --git a/tests/sys/netpfil/pf/sctp.sh b/tests/sys/netpfil/pf/sctp.sh
index 78055f5a9dd2..47bf40181b1b 100644
--- a/tests/sys/netpfil/pf/sctp.sh
+++ b/tests/sys/netpfil/pf/sctp.sh
@@ -29,9 +29,6 @@
sctp_init()
{
pft_init
- if ! kldstat -q -m sctp; then
- atf_skip "This test requires SCTP"
- fi
}
atf_test_case "basic_v4" "cleanup"
@@ -39,6 +36,7 @@ basic_v4_head()
{
atf_set descr 'Basic SCTP connection over IPv4 passthrough'
atf_set require.user root
+ atf_set require.kmods sctp
}
basic_v4_body()
@@ -112,6 +110,7 @@ basic_v6_head()
{
atf_set descr 'Basic SCTP connection over IPv6'
atf_set require.user root
+ atf_set require.kmods sctp
}
basic_v6_body()
@@ -186,6 +185,7 @@ reuse_head()
{
atf_set descr 'Test handling dumb clients that reuse source ports'
atf_set require.user root
+ atf_set require.kmods sctp
}
reuse_body()
@@ -244,6 +244,7 @@ abort_v4_head()
{
atf_set descr 'Test sending ABORT messages'
atf_set require.user root
+ atf_set require.kmods sctp
}
abort_v4_body()
@@ -302,6 +303,7 @@ abort_v6_head()
{
atf_set descr 'Test sending ABORT messages over IPv6'
atf_set require.user root
+ atf_set require.kmods sctp
}
abort_v6_body()
@@ -360,6 +362,7 @@ nat_v4_head()
{
atf_set descr 'Test NAT-ing SCTP over IPv4'
atf_set require.user root
+ atf_set require.kmods sctp
}
nat_v4_body()
@@ -412,6 +415,7 @@ nat_v6_head()
{
atf_set descr 'Test NAT-ing SCTP over IPv6'
atf_set require.user root
+ atf_set require.kmods sctp
}
nat_v6_body()
@@ -464,6 +468,7 @@ rdr_v4_head()
{
atf_set descr 'Test rdr SCTP over IPv4'
atf_set require.user root
+ atf_set require.kmods sctp
}
rdr_v4_body()
@@ -531,6 +536,7 @@ pfsync_head()
{
atf_set descr 'Test pfsync-ing SCTP connections'
atf_set require.user root
+ atf_set require.kmods carp sctp
}
pfsync_body()
@@ -563,10 +569,6 @@ pfsync_body()
sctp_init
pfsynct_init
vnet_init_bridge
- if ! kldstat -q -m carp
- then
- atf_skip "This test requires carp"
- fi
j="sctp:pfsync"
@@ -722,6 +724,7 @@ timeout_head()
{
atf_set descr 'Test setting and retrieving timeout values'
atf_set require.user root
+ atf_set require.kmods sctp
}
timeout_body()
@@ -753,6 +756,7 @@ related_icmp_head()
{
atf_set descr 'Verify that ICMP messages related to an SCTP connection are allowed'
atf_set require.user root
+ atf_set require.kmods sctp
}
related_icmp_body()
diff --git a/tools/test/stress2/misc/kevent17.sh b/tools/test/stress2/misc/kevent17.sh
new file mode 100755
index 000000000000..e7b8f1a0a00c
--- /dev/null
+++ b/tools/test/stress2/misc/kevent17.sh
@@ -0,0 +1,176 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# A kqueuex(KQUEUE_CPONFORK) test scenario
+# Test scenario suggestion by: kib
+
+. ../default.cfg
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+dir=/tmp
+odir=`pwd`
+prog=$(basename "$0" .sh)
+cd $dir
+sed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
+mycc -o $prog -Wall -Wextra -O0 -g $prog.c || exit 1
+rm -f $prog.c
+cd $odir
+
+set -e
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100 > /dev/null) &
+cd $mntpoint
+$dir/$prog
+s=$?
+[ -f $prog.core -a $s -eq 0 ] &&
+ { ls -l $prog.core; mv $prog.core /tmp; s=1; }
+cd $odir
+while pkill -9 swap; do :; done
+wait
+
+for i in `jot 6`; do
+ mount | grep -q "on $mntpoint " || break
+ umount $mntpoint && break || sleep 10
+done
+[ $i -eq 6 ] && exit 1
+mdconfig -d -u $mdstart
+rm -rf $dir/$prog
+exit $s
+
+EOF
+#include <sys/param.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <machine/atomic.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static volatile u_int *share;
+static int loops;
+static char *file = "file";
+
+#define MAXLOOPS 100
+#define PARALLEL 1
+#define RUNTIME (2 * 60)
+#define SYNC 0
+
+static void
+test(void)
+{
+ pid_t pid;
+ struct kevent ev[2];
+ struct timespec ts;
+ int kq, fd, n;
+
+ if ((fd = open(file, O_RDONLY, 0)) == -1)
+ err(1, "open(%s). %s:%d", file, __func__, __LINE__);
+
+ atomic_add_int(&share[SYNC], 1);
+ while (share[SYNC] != PARALLEL)
+ usleep(10000);
+
+ if ((kq = kqueuex(KQUEUE_CPONFORK)) < 0)
+ err(1, "kqueuex");
+
+ ts.tv_sec = 5;
+ ts.tv_nsec = 0;
+ n = 0;
+ EV_SET(&ev[n], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_DELETE, 0, 0);
+ n++;
+
+ if (kevent(kq, ev, n, NULL, 0, NULL) < 0)
+ err(1, "kevent()");
+ if (loops >= MAXLOOPS) { /* start using fork(2) */
+ if ((pid = fork()) == 0) {
+ n = kevent(kq, NULL, 0, ev, 1, &ts);
+ if (n == -1)
+ err(1, "kevent() in fork\n");
+ close(fd);
+ close(kq);
+ _exit(0);
+ }
+ if (waitpid(pid, NULL, 0) != pid)
+ err(1, "waitpid(%d)\n", pid);
+ }
+
+ n = kevent(kq, NULL, 0, ev, 1, &ts);
+ if (n == -1)
+ err(1, "kevent()");
+ close(fd);
+ close(kq);
+
+ _exit(0);
+}
+
+int
+main(void)
+{
+ pid_t pids[PARALLEL];
+ size_t len;
+ time_t start;
+ int e, fd, i, status;
+
+ e = 0;
+ len = PAGE_SIZE;
+ loops = 0;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME && e == 0) {
+ loops++;
+ if ((fd = open(file, O_CREAT | O_TRUNC | O_RDWR, 0660)) ==
+ -1)
+ err(1, "open(%s)", file);
+ close(fd);
+ share[SYNC] = 0;
+ for (i = 0; i < PARALLEL; i++) {
+
+ if ((pids[i] = fork()) == 0)
+ test();
+ if (pids[i] == -1)
+ err(1, "fork()");
+ }
+ while (share[SYNC] != PARALLEL)
+ usleep(10000);
+ if (unlink(file) == -1)
+ err(1, "unlink(%s). %s:%d\n", file,
+ __FILE__, __LINE__);
+ for (i = 0; i < PARALLEL; i++) {
+ if (waitpid(pids[i], &status, 0) == -1)
+ err(1, "waitpid(%d)", pids[i]);
+ if (status != 0) {
+ if (WIFSIGNALED(status))
+ fprintf(stderr,
+ "pid %d exit signal %d\n",
+ pids[i], WTERMSIG(status));
+ }
+ e += status == 0 ? 0 : 1;
+ }
+ }
+
+ return (e);
+}
diff --git a/tools/test/stress2/misc/kevent18.sh b/tools/test/stress2/misc/kevent18.sh
new file mode 100755
index 000000000000..1492c49e2921
--- /dev/null
+++ b/tools/test/stress2/misc/kevent18.sh
@@ -0,0 +1,152 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# A kqueuex(KQUEUE_CPONFORK) test scenario
+
+# Sleeping thread seen in WiP code:
+# https://people.freebsd.org/~pho/stress/log/log0615.txt
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+ulimit -k 5000 || { echo FAIL; exit 1; }
+
+odir=`pwd`
+prog=$(basename "$0" .sh)
+
+cd /tmp
+sed '1,/^EOF/d' < $odir/$0 > $prog.c
+mycc -o $prog -Wall -Wextra -O2 -g $prog.c -lpthread || exit 1
+rm -f $prog.c
+cd $odir
+
+mount | grep "on $mntpoint " | grep -q md$mdstart && umount -f $mntpoint
+mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart
+
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+chmod 777 $mntpoint
+
+su $testuser -c "(cd $mntpoint; /tmp/$prog)" &
+for i in `jot 99`; do
+ sleep 1
+ kill -0 $! 2>/dev/null || break
+done
+pkill $prog
+wait
+umount -f $mntpoint
+
+while mount | grep -q $mntpoint; do
+ umount $mntpoint || sleep 1
+done
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog
+
+exit 0
+EOF
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define PARALLEL 64
+
+static int fd;
+static char path[80];
+
+static void *
+spin(void *arg __unused)
+{
+ int i;
+
+ for (i= 0;; i++) {
+ snprintf(path, sizeof(path), "file.%06d.%d", getpid(), i);
+ fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622);
+ if (fd == -1 && errno == ENOTDIR)
+ break;
+ if (fd == -1)
+ err(1, "open(%s)", path);
+ close(fd);
+ fd = 0;
+ unlink(path);
+ }
+ fprintf(stderr, "spin loops: %d\n", i + 1);
+ return (NULL);
+}
+
+static void *
+test(void *arg __unused)
+{
+ struct kevent ev;
+ struct timespec ts;
+ pid_t pid;
+ int i, kq, n;
+
+ for (i = 0; i < 500000; i++) {
+ if ((kq = kqueuex(KQUEUE_CPONFORK)) < 0)
+ err(1, "kqueueex(KQUEUE_CPONFORK)");
+
+ n = 0;
+ memset(&ev, 0, sizeof(ev));
+ EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_DELETE|NOTE_RENAME|NOTE_EXTEND, 0, 0);
+ n++;
+
+ if ((pid = fork()) == 0) {
+ kevent(kq, &ev, n, NULL, 0, NULL);
+ _exit(0);
+ }
+ if (waitpid(pid, NULL, 0) != pid)
+ err(1, "waitpid(%d)", pid);
+
+ kevent(kq, &ev, n, NULL, 0, NULL);
+ memset(&ev, 0, sizeof(ev));
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1000000;
+ if ((n = kevent(kq, NULL, 0, &ev, 1, &ts)) == -1)
+ err(1, "kevent()");
+
+ close(kq);
+ }
+ return (NULL);
+}
+
+int
+main(void)
+{
+ pthread_t cp[PARALLEL], sp;
+ int e, i;
+
+ if ((e = pthread_create(&sp, NULL, spin, NULL)) != 0)
+ errc(1, e, "pthread_create");
+
+ for (i = 0; i < PARALLEL; i++) {
+ if ((e = pthread_create(&cp[i], NULL, test, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+
+ for (i = 0; i < PARALLEL; i++)
+ pthread_join(cp[i], NULL);
+ pthread_join(sp, NULL);
+
+ close(fd);
+
+ return (0);
+}
diff --git a/tools/test/stress2/misc/kevent19.sh b/tools/test/stress2/misc/kevent19.sh
new file mode 100755
index 000000000000..0170fe0d93c8
--- /dev/null
+++ b/tools/test/stress2/misc/kevent19.sh
@@ -0,0 +1,187 @@
+#!/bin/sh
+
+# A kqueuex(KQUEUE_CPONFORK) test scenario
+
+set -u
+prog=$(basename "$0" .sh)
+
+cat > /tmp/$prog.c <<EOF
+/* \$Id: kqfork.c,v 1.4 2025/08/19 19:42:16 kostik Exp kostik $ */
+
+#include <sys/param.h>
+#include <sys/event.h>
+#include <err.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef KQUEUE_CPONFORK
+#define KQUEUE_CPONFORK 0x2
+#endif
+
+static pid_t pid_pipe_beat;
+static pid_t pid_controller;
+
+static void
+sighup_handler(int sig __unused)
+{
+ kill(pid_pipe_beat, SIGKILL);
+ _exit(1);
+}
+
+static void
+pipe_beat(int wp)
+{
+ static const char a[1] = { 'a' };
+ ssize_t s;
+
+ for (;;) {
+ sleep(1);
+ s = write(wp, a, 1);
+ if (s < 0)
+ err(1, "pipe write");
+ if (s == 0)
+ errx(1, "short pipe write");
+ }
+}
+
+static void
+worker(int kq, int rp)
+{
+ struct kevent ev[1];
+ char a[1];
+ ssize_t s;
+ int n;
+
+ for (;;) {
+ n = kevent(kq, NULL, 0, ev, nitems(ev), NULL);
+ if (n == -1) {
+ kill(pid_controller, SIGHUP);
+ err(1, "kqueue");
+ }
+ if (n == 0)
+ continue; // XXXKIB
+ switch (ev[0].filter) {
+ case EVFILT_TIMER:
+ printf("tick\n");
+ break;
+ case EVFILT_READ:
+ if (ev[0].ident != (uintptr_t)rp) {
+ kill(pid_controller, SIGHUP);
+ errx(1, "unknown read ident %d\n", (int)ev[0].ident);
+ }
+ s = read(rp, a, sizeof(a));
+ if (s == -1) {
+ kill(pid_controller, SIGHUP);
+ err(1, "read");
+ }
+ if (s == 0) {
+ kill(pid_controller, SIGHUP);
+ errx(1, "EOF");
+ }
+ printf("%c\n", a[0]);
+ break;
+ default:
+ kill(pid_controller, SIGHUP);
+ errx(1, "unknown fiter %d\n", ev[0].filter);
+ break;
+ }
+ }
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: kqfork [fork]\n");
+ exit(2);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct kevent ev[2];
+ struct sigaction sa;
+ int kq, n, pp[2];
+ pid_t pid_worker;
+ bool do_fork;
+
+ do_fork = false;
+ if (argc != 1 && argc != 2)
+ usage();
+ if (argc == 2) {
+ if (strcmp(argv[1], "fork") != 0)
+ usage();
+ do_fork = true;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sighup_handler;
+ if (sigaction(SIGHUP, &sa, NULL) == -1)
+ err(1, "sigaction(SIGHUP)");
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NOCLDWAIT | SA_NOCLDSTOP;
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGCHLD, &sa, NULL) == -1)
+ err(1, "sigaction(SIGCHLD)");
+
+ if (pipe(pp) == -1)
+ err(1, "pipe");
+
+ pid_pipe_beat = fork();
+ if (pid_pipe_beat == -1)
+ err(1, "fork");
+ if (pid_pipe_beat == 0) {
+ close(pp[0]);
+ pipe_beat(pp[1]);
+ }
+
+ kq = kqueuex(do_fork ? KQUEUE_CPONFORK : 0);
+ if (kq == -1)
+ err(1, "kqueuex");
+
+ EV_SET(&ev[0], 1, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, 1, NULL);
+ EV_SET(&ev[1], pp[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
+ n = kevent(kq, ev, nitems(ev), NULL, 0, NULL);
+ if (n == -1) {
+ kill(pid_pipe_beat, SIGKILL);
+ err(1, "kevent reg");
+ }
+ if (n != 0) {
+ kill(pid_pipe_beat, SIGKILL);
+ errx(1, "kevent reg %d", n);
+ }
+
+ pid_controller = getpid();
+
+ if (do_fork) {
+ pid_worker = fork();
+ if (pid_worker == -1) {
+ kill(pid_pipe_beat, SIGKILL);
+ err(1, "fork");
+ }
+ if (pid_worker == 0) {
+ close(pp[1]);
+ worker(kq, pp[0]);
+ }
+
+ for (;;)
+ pause();
+ } else {
+ worker(kq, pp[0]);
+ }
+ exit(0); // unreachable
+}
+EOF
+cc -o /tmp/$prog -Wall -Wextra -O2 /tmp/$prog.c || exit 1
+
+echo "--> No fork"
+timeout 4s /tmp/$prog
+echo "--> fork"
+timeout 4s /tmp/$prog fork
+
+rm -f /tmp/$prog.c $prog
+exit 0
diff --git a/tools/tools/git/mfc-candidates.lua b/tools/tools/git/mfc-candidates.lua
index a1420dc726da..cbf7dcb3a257 100755
--- a/tools/tools/git/mfc-candidates.lua
+++ b/tools/tools/git/mfc-candidates.lua
@@ -117,7 +117,7 @@ end
local function usage(from_branch, to_branch, author)
local script_name = arg[0]:match("([^/]+)$")
- print(script_name .. " [-ah] [-f from_branch] [-t to_branch] [-u user] [-X exclude_file] [path ...]")
+ print(script_name .. " [-ah] [-F git-show-fmt] [-f from_branch] [-t to_branch] [-u user] [-X exclude_file] [path ...]")
print()
params(from_branch, to_branch, author)
end
@@ -162,6 +162,7 @@ local function main()
local do_help = false
local exclude_file = nil
+ local gitshowfmt = '%h %s'
local i = 1
while i <= #arg and arg[i] do
local opt = arg[i]
@@ -181,6 +182,9 @@ local function main()
i = i + 1
elseif opt == "-v" then
verbose = verbose + 1
+ elseif opt == "-F" then
+ gitshowfmt = arg[i + 1]
+ i = i + 1
elseif opt == "-X" then
exclude_file = arg[i + 1]
i = i + 1
@@ -217,7 +221,7 @@ local function main()
-- Print the result
for _, hash in ipairs(result_hashes) do
- print(exec_command("git show --pretty='%h %s' --no-patch " .. hash))
+ print(exec_command("git show --pretty='" .. gitshowfmt .. "' --no-patch " .. hash))
end
end
diff --git a/usr.bin/bsdcat/Makefile b/usr.bin/bsdcat/Makefile
index 032207217be6..06081fc2b2f8 100644
--- a/usr.bin/bsdcat/Makefile
+++ b/usr.bin/bsdcat/Makefile
@@ -11,7 +11,7 @@ BSDCAT_VERSION_STRING!= sed -n '/define.*ARCHIVE_VERSION_ONLY_STRING/{s,[^0-9.],
SRCS= bsdcat.c cmdline.c
.PATH: ${_LIBARCHIVEDIR}/libarchive_fe
-SRCS+= err.c
+SRCS+= lafe_err.c
CFLAGS+= -DBSDCAT_VERSION_STRING=\"${BSDCAT_VERSION_STRING}\"
CFLAGS+= -DPLATFORM_CONFIG_H=\"${_LIBARCHIVECONFDIR}/config_freebsd.h\"
diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile
index 46fe36d8c18e..31b25e4199da 100644
--- a/usr.bin/cpio/Makefile
+++ b/usr.bin/cpio/Makefile
@@ -11,7 +11,7 @@ BSDCPIO_VERSION_STRING!= sed -n '/define.*ARCHIVE_VERSION_ONLY_STRING/{s,[^0-9.]
SRCS= cpio.c cmdline.c
.PATH: ${_LIBARCHIVEDIR}/libarchive_fe
-SRCS+= err.c line_reader.c passphrase.c
+SRCS+= lafe_err.c line_reader.c passphrase.c
CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\"
CFLAGS+= -DPLATFORM_CONFIG_H=\"${_LIBARCHIVECONFDIR}/config_freebsd.h\"
diff --git a/usr.bin/cpio/tests/Makefile b/usr.bin/cpio/tests/Makefile
index 9e1028c7eb58..ee4da15bc7e4 100644
--- a/usr.bin/cpio/tests/Makefile
+++ b/usr.bin/cpio/tests/Makefile
@@ -26,7 +26,7 @@ CFLAGS.test_utils.c+= -Wno-cast-align
CPIO_SRCS= cmdline.c
.PATH: ${_LIBARCHIVEDIR}/libarchive_fe
-CPIO_SRCS+= err.c
+CPIO_SRCS+= lafe_err.c
.PATH: ${_LIBARCHIVEDIR}/cpio/test
TESTS_SRCS= \
diff --git a/usr.bin/find/find.c b/usr.bin/find/find.c
index 8b24ecd6a306..2247ae86a94b 100644
--- a/usr.bin/find/find.c
+++ b/usr.bin/find/find.c
@@ -211,7 +211,7 @@ find_execute(PLAN *plan, char *paths[])
}
if (showinfo) {
- fprintf(stderr, "Scanning: %s/%s\n", entry->fts_path, entry->fts_name);
+ fprintf(stderr, "Scanning: %s\n", entry->fts_path);
fprintf(stderr, "Scanned: %zu\n\n", counter);
showinfo = 0;
}
diff --git a/usr.bin/mkimg/mkimg.c b/usr.bin/mkimg/mkimg.c
index a7409b686560..27b79b82ca02 100644
--- a/usr.bin/mkimg/mkimg.c
+++ b/usr.bin/mkimg/mkimg.c
@@ -142,8 +142,10 @@ static void
usage(const char *why)
{
- warnx("error: %s", why);
- fputc('\n', stderr);
+ if (why != NULL) {
+ warnx("error: %s", why);
+ fputc('\n', stderr);
+ }
fprintf(stderr, "usage: %s <options>\n", getprogname());
fprintf(stderr, " options:\n");
@@ -171,19 +173,19 @@ usage(const char *why)
print_schemes(1);
fputc('\n', stderr);
fprintf(stderr, " partition specification:\n");
- fprintf(stderr, "\t<t>[/<l>]::<size>[:[+]<offset>]\t- "
+ fprintf(stderr, "\t<type>[/<label>]::<size>[:[+]<offset>]\t- "
"empty partition of given size and\n\t\t\t\t\t"
" optional relative or absolute offset\n");
- fprintf(stderr, "\t<t>[/<l>]:=<file>[:[+]offset]\t- partition "
+ fprintf(stderr, "\t<type>[/<label>]:=<file>[:[+]offset]\t- partition "
"content and size are\n\t\t\t\t\t"
" determined by the named file and\n"
"\t\t\t\t\t optional relative or absolute offset\n");
- fprintf(stderr, "\t<t>[/<l>]:-<cmd>\t\t- partition content and size "
+ fprintf(stderr, "\t<type>[/<label>]:-<cmd>\t\t- partition content and size "
"are taken\n\t\t\t\t\t from the output of the command to run\n");
fprintf(stderr, "\t-\t\t\t\t- unused partition entry\n");
fprintf(stderr, "\t where:\n");
- fprintf(stderr, "\t\t<t>\t- scheme neutral partition type\n");
- fprintf(stderr, "\t\t<l>\t- optional scheme-dependent partition "
+ fprintf(stderr, "\t\t<type>\t- scheme neutral partition type\n");
+ fprintf(stderr, "\t\t<label>\t- optional scheme-dependent partition "
"label\n");
exit(EX_USAGE);
@@ -564,7 +566,7 @@ main(int argc, char *argv[])
bcfd = -1;
outfd = 1; /* Write to stdout by default */
- while ((c = getopt_long(argc, argv, "a:b:c:C:f:o:p:s:t:vyH:P:S:T:",
+ while ((c = getopt_long(argc, argv, "a:b:c:C:f:ho:p:s:t:vyH:P:S:T:",
longopts, NULL)) != -1) {
switch (c) {
case 'a': /* ACTIVE PARTITION, if supported */
@@ -596,6 +598,9 @@ main(int argc, char *argv[])
if (error)
errc(EX_DATAERR, error, "format");
break;
+ case 'h': /* HELP */
+ usage(NULL);
+ break;
case 'o': /* OUTPUT FILE */
if (outfd != 1)
usage("multiple output files given");
diff --git a/usr.bin/ncurses/Makefile b/usr.bin/ncurses/Makefile
index 33001e6ab568..1ed8a2d9a915 100644
--- a/usr.bin/ncurses/Makefile
+++ b/usr.bin/ncurses/Makefile
@@ -1,4 +1,4 @@
-PACKAGE= runtime
+PACKAGE= ncurses
.include <bsd.own.mk>
.include "${SRCTOP}/lib/ncurses/config.mk"
diff --git a/usr.bin/sockstat/main.c b/usr.bin/sockstat/main.c
index d1ea6b1bc958..abb73acafc2f 100644
--- a/usr.bin/sockstat/main.c
+++ b/usr.bin/sockstat/main.c
@@ -1196,7 +1196,9 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
first = true;
len = strlen(s->protoname);
- if (s->vflag & (INP_IPV4 | INP_IPV6))
+ if (s->vflag & INP_IPV4)
+ len += 1;
+ if (s->vflag & INP_IPV6)
len += 1;
cw->proto = MAX(cw->proto, len);
diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile
index d3d29e03fd35..8b0d3e4a6cf0 100644
--- a/usr.bin/tar/Makefile
+++ b/usr.bin/tar/Makefile
@@ -2,6 +2,7 @@
_LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive
+PACKAGE= runtime
PROG= bsdtar
BSDTAR_VERSION_STRING!= sed -n '/define.*ARCHIVE_VERSION_ONLY_STRING/{s,[^0-9.],,gp;q;}' \
${_LIBARCHIVEDIR}/libarchive/archive.h
@@ -16,7 +17,7 @@ SRCS= bsdtar.c \
write.c
.PATH: ${_LIBARCHIVEDIR}/libarchive_fe
-SRCS+= err.c \
+SRCS+= lafe_err.c \
line_reader.c \
passphrase.c
diff --git a/usr.bin/tar/tests/Makefile b/usr.bin/tar/tests/Makefile
index 929f8127f9b3..116425b0621f 100644
--- a/usr.bin/tar/tests/Makefile
+++ b/usr.bin/tar/tests/Makefile
@@ -27,6 +27,7 @@ TESTS_SRCS= \
test_0.c \
test_basic.c \
test_copy.c \
+ test_crlf_mtree.c \
test_empty_mtree.c \
test_extract_tar_bz2.c \
test_extract_tar_grz.c \
diff --git a/usr.bin/unzip/Makefile b/usr.bin/unzip/Makefile
index 2db5e9ac4c99..63f49a203685 100644
--- a/usr.bin/unzip/Makefile
+++ b/usr.bin/unzip/Makefile
@@ -12,7 +12,7 @@ BSDUNZIP_VERSION_STRING!= sed -n '/define.*ARCHIVE_VERSION_ONLY_STRING/{s,[^0-9.
SRCS= bsdunzip.c
.PATH: ${_LIBARCHIVEDIR}/libarchive_fe
-SRCS+= cmdline.c err.c passphrase.c
+SRCS+= cmdline.c lafe_err.c passphrase.c
CFLAGS+= -DBSDUNZIP_VERSION_STRING=\"${BSDUNZIP_VERSION_STRING}\"
CFLAGS+= -DPLATFORM_CONFIG_H=\"${_LIBARCHIVECONFDIR}/config_freebsd.h\"
diff --git a/usr.bin/unzip/tests/Makefile b/usr.bin/unzip/tests/Makefile
index 404a546410e4..fada172b1bd7 100644
--- a/usr.bin/unzip/tests/Makefile
+++ b/usr.bin/unzip/tests/Makefile
@@ -23,7 +23,7 @@ CFLAGS+= -I${_LIBARCHIVEDIR}/libarchive_fe -I${_LIBARCHIVEDIR}/test_utils
CFLAGS.test_utils.c+= -Wno-cast-align
.PATH: ${_LIBARCHIVEDIR}/libarchive_fe
-UNZIP_SRCS+= err.c
+UNZIP_SRCS+= lafe_err.c
.PATH: ${_LIBARCHIVEDIR}/unzip/test
TESTS_SRCS= \
diff --git a/usr.sbin/bsdinstall/Makefile b/usr.sbin/bsdinstall/Makefile
index e5bb3197fa05..5d7be97ed7cf 100644
--- a/usr.sbin/bsdinstall/Makefile
+++ b/usr.sbin/bsdinstall/Makefile
@@ -22,7 +22,8 @@ REVISION?= ${_REVISION}
.if ${BRANCH} == CURRENT || ${BRANCH} == STABLE
SUBURL= base_latest
-.elif ${BRANCH} == RELEASE
+.elif ${BRANCH} == RELEASE || ${BRANCH:C/[0-9]+$//} == BETA || \
+ ${BRANCH:C/[0-9]+$//} == RC
SUBURL= base_release_${REVISION:C/[0-9]+\.//}
.else
.warning Invalid branch "${BRANCH}"
diff --git a/usr.sbin/bsdinstall/scripts/auto b/usr.sbin/bsdinstall/scripts/auto
index 8058b1a41dbf..5fefc07e4c07 100755
--- a/usr.sbin/bsdinstall/scripts/auto
+++ b/usr.sbin/bsdinstall/scripts/auto
@@ -73,7 +73,7 @@ msg_yes="YES"
# error [$msg]
#
# Display generic error message when a script fails. An optional message
-# argument can preceed the generic message. User is given the choice of
+# argument can precede the generic message. User is given the choice of
# restarting the installer or exiting.
#
error()
diff --git a/usr.sbin/bsdinstall/scripts/bootconfig b/usr.sbin/bsdinstall/scripts/bootconfig
index 6736e78b450a..9c188c1d8a91 100755
--- a/usr.sbin/bsdinstall/scripts/bootconfig
+++ b/usr.sbin/bsdinstall/scripts/bootconfig
@@ -163,7 +163,7 @@ if [ -n "$(awk '{if ($2=="/boot/efi") printf("%s\n",$1);}' $PATH_FSTAB)" ]; then
rmdir "${mntpt}"
fi
- # Try to set the UEFI NV BootXXXX variables to recod the boot location
+ # Try to set the UEFI NV BootXXXX variables to record the boot location
if [ "$BSDINSTALL_CONFIGCURRENT" ] && [ "$ARCHBOOTNAME" != ia32 ]; then
update_uefi_bootentry
fi
diff --git a/usr.sbin/bsdinstall/scripts/jail b/usr.sbin/bsdinstall/scripts/jail
index 3b1b2ee98fff..e4238ac0a687 100755
--- a/usr.sbin/bsdinstall/scripts/jail
+++ b/usr.sbin/bsdinstall/scripts/jail
@@ -45,7 +45,7 @@ user_env_vars="BSDINSTALL_DISTSITE DISTRIBUTIONS"
# error [$msg]
#
# Display generic error message when a script fails. An optional message
-# argument can preceed the generic message. User is given the choice of
+# argument can precede the generic message. User is given the choice of
# restarting the installer or exiting.
#
error() {
@@ -79,7 +79,7 @@ distbase() {
: ${DISTRIBUTIONS="base.txz"}; export DISTRIBUTIONS
if [ -f $BSDINSTALL_DISTDIR/MANIFEST ]; then
- DISTMENU=`cut -f 4,5,6 $BSDINSTALL_DISTDIR/MANIFEST | grep -v -e ^kernel -e ^base`
+ DISTMENU=$(cut -f 1,5,6 $BSDINSTALL_DISTDIR/MANIFEST | grep -v -e ^kernel -e ^base | sed -E 's/\.txz//g')
if [ ! "$nonInteractive" == "YES" ]
then
diff --git a/usr.sbin/bsdinstall/scripts/keymap b/usr.sbin/bsdinstall/scripts/keymap
index 6f4060c0772e..669a1062df95 100755
--- a/usr.sbin/bsdinstall/scripts/keymap
+++ b/usr.sbin/bsdinstall/scripts/keymap
@@ -216,7 +216,7 @@ while :; do
n=$( eval f_dialog_menutag2index_with_help \
\"\$menu_choice\" $menu_list )
- # Turn that number ithe name of the keymap struct
+ # Turn that number into the name of the keymap struct
k=$( set -- $KEYMAPS; eval echo \"\${$(( $n - 2))}\" )
# Get actual keymap setting while we update $keymap and $KEYMAPFILE
diff --git a/usr.sbin/bsdinstall/scripts/script b/usr.sbin/bsdinstall/scripts/script
index 00ded5f8e24d..21da2ea7c366 100755
--- a/usr.sbin/bsdinstall/scripts/script
+++ b/usr.sbin/bsdinstall/scripts/script
@@ -144,7 +144,7 @@ else
#
# Work around this in an extremely lame way for the specific
# case of EFI system partitions only. This *ONLY WORKS* if
- # /boot/efi is empty and does not handle analagous problems on
+ # /boot/efi is empty and does not handle analogous problems on
# other systems (ARM, PPC64).
tar -xf "$BSDINSTALL_DISTDIR/$set" -C $BSDINSTALL_CHROOT --exclude boot/efi
mkdir -p $BSDINSTALL_CHROOT/boot/efi
diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot
index 95cbba3fa131..9ea6ec3a4ac9 100755
--- a/usr.sbin/bsdinstall/scripts/zfsboot
+++ b/usr.sbin/bsdinstall/scripts/zfsboot
@@ -255,7 +255,7 @@ msg_encrypt_disks="Encrypt Disks?"
msg_encrypt_disks_help="Use geli(8) to encrypt all data partitions"
msg_error="Error"
msg_force_4k_sectors="Force 4K Sectors?"
-msg_force_4k_sectors_help="Align partitions to 4K sector boundries and set vfs.zfs.vdev.min_auto_ashift=12"
+msg_force_4k_sectors_help="Align partitions to 4K sector boundaries and set vfs.zfs.vdev.min_auto_ashift=12"
msg_freebsd_installer="$OSNAME Installer"
msg_geli_password="Enter a strong passphrase, used to protect your encryption keys. You will be required to enter this passphrase each time the system is booted"
msg_geli_setup="Initializing encryption on selected disks,\n this will take several seconds per disk"
diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c
index ade99464a4a3..63684f800bdc 100644
--- a/usr.sbin/pmcstat/pmcpl_callgraph.c
+++ b/usr.sbin/pmcstat/pmcpl_callgraph.c
@@ -362,7 +362,7 @@ pmcpl_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
* - Find the function that overlaps the return address.
* - If found: use the start address of the function.
* If not found (say an object's symbol table is not present or
- * is incomplete), round down to th gprof bucket granularity.
+ * is incomplete), round down to the gprof bucket granularity.
* - Convert return virtual address to an offset in the image.
* - Look for a child with the same {offset,image} tuple,
* inserting one if needed.
diff --git a/usr.sbin/quot/quot.c b/usr.sbin/quot/quot.c
index 879580f649b9..5dda36ac8499 100644
--- a/usr.sbin/quot/quot.c
+++ b/usr.sbin/quot/quot.c
@@ -178,20 +178,20 @@ static struct user {
daddr_t spc60;
daddr_t spc90;
} *users;
-static int nusers;
+static unsigned int nusers;
static void
inituser(void)
{
- int i;
struct user *usr;
+ unsigned int i;
if (nusers == 0) {
nusers = 8;
if ((users = calloc(nusers, sizeof(*users))) == NULL)
errx(1, "allocate users");
} else {
- for (usr = users, i = nusers; --i >= 0; usr++) {
+ for (usr = users, i = nusers; i-- > 0; usr++) {
usr->space = usr->spc30 = usr->spc60 = usr->spc90 = 0;
usr->count = 0;
}
@@ -201,15 +201,15 @@ inituser(void)
static void
usrrehash(void)
{
- int i;
struct user *usr, *usrn;
struct user *svusr;
+ unsigned int i;
svusr = users;
nusers *= 2;
if ((users = calloc(nusers, sizeof(*users))) == NULL)
errx(1, "allocate users");
- for (usr = svusr, i = nusers / 2; --i >= 0; usr++) {
+ for (usr = svusr, i = nusers / 2; i-- > 0; usr++) {
for (usrn = users + usr->uid % nusers; usrn->name; usrn--) {
if (usrn <= users)
usrn += nusers;
@@ -223,10 +223,10 @@ user(uid_t uid)
{
struct user *usr;
struct passwd *pwd;
- int i;
+ unsigned int i;
while (1) {
- for (usr = users + uid % nusers, i = nusers; --i >= 0; usr--) {
+ for (usr = users + uid % nusers, i = nusers; i-- > 0; usr--) {
if (usr->name == NULL) {
usr->uid = uid;
if (noname || (pwd = getpwuid(uid)) == NULL)
@@ -280,7 +280,7 @@ uses(uid_t uid, daddr_t blks, time_t act)
usr->spc30 += blks;
}
-#define FSZCNT 512
+#define FSZCNT 512U
static struct fsizes {
struct fsizes *fsz_next;
daddr_t fsz_first, fsz_last;
@@ -292,10 +292,10 @@ static void
initfsizes(void)
{
struct fsizes *fp;
- int i;
+ unsigned int i;
for (fp = fsizes; fp; fp = fp->fsz_next) {
- for (i = FSZCNT; --i >= 0;) {
+ for (i = FSZCNT; i-- > 0;) {
fp->fsz_count[i] = 0;
fp->fsz_sz[i] = 0;
}
@@ -309,13 +309,12 @@ dofsizes(int fd, struct fs *super)
union dinode *dp;
daddr_t sz, ksz;
struct fsizes *fp, **fsp;
- int i;
+ unsigned int i;
maxino = super->fs_ncg * super->fs_ipg - 1;
for (inode = 0; inode < maxino; inode++) {
if ((dp = get_inode(fd, super, inode)) != NULL &&
- !isfree(super, dp)
- ) {
+ !isfree(super, dp)) {
sz = DIP(super, dp, di_blocks);
ksz = SIZE(sz);
for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) {
@@ -329,7 +328,7 @@ dofsizes(int fd, struct fs *super)
*fsp = fp;
fp->fsz_first = rounddown(ksz, FSZCNT);
fp->fsz_last = fp->fsz_first + FSZCNT;
- for (i = FSZCNT; --i >= 0;) {
+ for (i = FSZCNT; i-- > 0;) {
fp->fsz_count[i] = 0;
fp->fsz_sz[i] = 0;
}
diff --git a/usr.sbin/sndctl/sndctl.c b/usr.sbin/sndctl/sndctl.c
index 156c845481c5..6977f0ab0ebe 100644
--- a/usr.sbin/sndctl/sndctl.c
+++ b/usr.sbin/sndctl/sndctl.c
@@ -830,6 +830,8 @@ mod_play_vchans(struct snd_dev *dp, void *arg)
if (dp->from_user)
return (-1);
+ if (!dp->play.pchans)
+ return (0);
snprintf(buf, sizeof(buf), "dev.pcm.%d.play.vchans", dp->unit);
@@ -873,6 +875,8 @@ mod_rec_vchans(struct snd_dev *dp, void *arg)
if (dp->from_user)
return (-1);
+ if (!dp->rec.pchans)
+ return (0);
snprintf(buf, sizeof(buf), "dev.pcm.%d.rec.vchans", dp->unit);
diff --git a/usr.sbin/virtual_oss/virtual_bt_speaker/bt_speaker.c b/usr.sbin/virtual_oss/virtual_bt_speaker/bt_speaker.c
index c61eaf1c338d..0e406cccca21 100644
--- a/usr.sbin/virtual_oss/virtual_bt_speaker/bt_speaker.c
+++ b/usr.sbin/virtual_oss/virtual_bt_speaker/bt_speaker.c
@@ -47,7 +47,6 @@
#include "avdtp_signal.h"
#include "bt.h"
-#include "utils.h"
static int (*bt_receive_f)(struct bt_config *, void *, int, int);
static int (*avdtpACPHandlePacket_f)(struct bt_config *cfg);
diff --git a/usr.sbin/virtual_oss/virtual_oss/int.h b/usr.sbin/virtual_oss/virtual_oss/int.h
index b3cc573ba8a9..69a943832074 100644
--- a/usr.sbin/virtual_oss/virtual_oss/int.h
+++ b/usr.sbin/virtual_oss/virtual_oss/int.h
@@ -318,9 +318,6 @@ extern void vclient_rx_equalizer(struct virtual_client *, int64_t *, size_t);
extern int vclient_eq_alloc(struct virtual_client *);
extern void vclient_eq_free(struct virtual_client *);
-/* Internal utilities */
-extern int bt_speaker_main(int argc, char **argv);
-
/* Internal compressor */
extern void voss_compressor(int64_t *, double *, const struct virtual_compressor *,
const unsigned, const unsigned, const int64_t);
diff --git a/usr.sbin/virtual_oss/virtual_oss/main.c b/usr.sbin/virtual_oss/virtual_oss/main.c
index 3f7fb84ce4c6..afa4ad0727ca 100644
--- a/usr.sbin/virtual_oss/virtual_oss/main.c
+++ b/usr.sbin/virtual_oss/virtual_oss/main.c
@@ -48,7 +48,6 @@
#include "backend.h"
#include "int.h"
-#include "utils.h"
#include "virtual_oss.h"
pthread_mutex_t atomic_mtx;
diff --git a/usr.sbin/virtual_oss/virtual_oss/utils.h b/usr.sbin/virtual_oss/virtual_oss/utils.h
deleted file mode 100644
index f0998dc75dae..000000000000
--- a/usr.sbin/virtual_oss/virtual_oss/utils.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*-
- * Copyright (c) 2019 Hans Petter Selasky
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _VIRTUAL_UTILS_H_
-#define _VIRTUAL_UTILS_H_
-
-int bt_speaker_main(int argc, char **argv);
-
-#endif /* _VIRTUAL_UTILS_H_ */