diff options
193 files changed, 2381 insertions, 1134 deletions
@@ -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/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/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/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/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/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/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/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/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/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/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/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/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..96676e8694bf 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -666,6 +666,7 @@ static const char *random_source_descr[ENTROPYSOURCE] = { [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/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/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/kern/kern_jail.c b/sys/kern/kern_jail.c index 00732d55cd46..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; } 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/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/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/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/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/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/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/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..dca30dc8fde4 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -94,6 +94,7 @@ enum random_entropy_source { RANDOM_PURE_GLXSB, RANDOM_PURE_HIFN, RANDOM_PURE_RDRAND, + RANDOM_PURE_RDSEED, RANDOM_PURE_NEHEMIAH, RANDOM_PURE_RNDTEST, RANDOM_PURE_VIRTIO, 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/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/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/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/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); |