diff options
154 files changed, 1590 insertions, 685 deletions
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/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.h index 7d090ba682b3..7ab63905ed4f 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.h @@ -78,11 +78,6 @@ public:    void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,                           llvm::opt::ArgStringList &CC1Args) const override; -  bool IsAArch64OutlineAtomicsDefault( -      const llvm::opt::ArgList &Args) const override { -    return true; -  } -    UnwindTableLevel    getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override;    bool isPIEDefault(const llvm::opt::ArgList &Args) const override; diff --git a/lib/libarchive/tests/Makefile b/lib/libarchive/tests/Makefile index 07c5fe24dd30..930250d974c5 100644 --- a/lib/libarchive/tests/Makefile +++ b/lib/libarchive/tests/Makefile @@ -185,6 +185,7 @@ TESTS_SRCS= \  	test_read_format_rar_overflow.c		\  	test_read_format_raw.c			\  	test_read_format_tar.c			\ +	test_read_format_tar_V_negative_size.c	\  	test_read_format_tar_concatenated.c	\  	test_read_format_tar_empty_filename.c	\  	test_read_format_tar_empty_pax.c	\ @@ -607,6 +608,7 @@ ${PACKAGE}FILES+=	test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_different_solid_window_size.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_different_window_size.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_different_winsize_on_merge.rar.uu +${PACKAGE}FILES+=	test_read_format_rar5_dirdata.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_distance_overflow.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_encrypted.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_encrypted_filenames.rar.uu @@ -616,6 +618,7 @@ ${PACKAGE}FILES+=	test_read_format_rar5_extra_field_version.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_fileattr.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_hardlink.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_invalid_dict_reference.rar.uu +${PACKAGE}FILES+=	test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_leftshift1.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_leftshift2.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_multiarchive.part01.rar.uu @@ -633,6 +636,7 @@ ${PACKAGE}FILES+=	test_read_format_rar5_multiarchive_solid.part04.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_multiple_files.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_multiple_files_solid.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_nonempty_dir_stream.rar.uu +${PACKAGE}FILES+=	test_read_format_rar5_only_crypt_exfld.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_owner.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_readtables_overflow.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_sfx.exe.uu @@ -642,12 +646,14 @@ ${PACKAGE}FILES+=	test_read_format_rar5_stored_manyfiles.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_symlink.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_truncated_huff.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_unicode.rar.uu +${PACKAGE}FILES+=	test_read_format_rar5_unsupported_exfld.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_win32.rar.uu  ${PACKAGE}FILES+=	test_read_format_rar5_window_buf_and_size_desync.rar.uu  ${PACKAGE}FILES+=	test_read_format_raw.bufr.uu  ${PACKAGE}FILES+=	test_read_format_raw.data.Z.uu  ${PACKAGE}FILES+=	test_read_format_raw.data.gz.uu  ${PACKAGE}FILES+=	test_read_format_raw.data.uu +${PACKAGE}FILES+=	test_read_format_tar_V_negative_size.tar.uu  ${PACKAGE}FILES+=	test_read_format_tar_concatenated.tar.uu  ${PACKAGE}FILES+=	test_read_format_tar_empty_filename.tar.uu  ${PACKAGE}FILES+=	test_read_format_tar_empty_with_gnulabel.tar.uu diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3 index 9365d043a1fc..19fa12419353 100644 --- a/lib/libc/gen/getvfsbyname.3 +++ b/lib/libc/gen/getvfsbyname.3 @@ -27,7 +27,7 @@  .\"  .\"     @(#)kvm_getvfsbyname.3	8.3 (Berkeley) 5/4/95  .\" -.Dd August 16, 2018 +.Dd October 28, 2025  .Dt GETVFSBYNAME 3  .Os  .Sh NAME @@ -104,6 +104,7 @@ argument  specifies a file system that is unknown or not configured in the kernel.  .El  .Sh SEE ALSO +.Xr lsvfs 1 ,  .Xr jail 2 ,  .Xr mount 2 ,  .Xr sysctl 3 , diff --git a/lib/libc/sys/revoke.2 b/lib/libc/sys/revoke.2 index dc92512d3129..db0c8a85558b 100644 --- a/lib/libc/sys/revoke.2 +++ b/lib/libc/sys/revoke.2 @@ -30,7 +30,7 @@  .\"  .\"     @(#)revoke.2	8.1 (Berkeley) 6/4/93  .\" -.Dd January 25, 2016 +.Dd October 24, 2025  .Dt REVOKE 2  .Os  .Sh NAME @@ -64,7 +64,7 @@ using a special close method which does not block.  Access to a file may be revoked only by its owner or the super user.  The  .Fn revoke -system call is currently supported only for block and character special +system call is currently supported only for character special  device files.  It is normally used to prepare a terminal device for a new login session,  preventing any access by a previous user of the terminal. diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2 index adf60aa91d7a..2f0a9d034038 100644 --- a/lib/libc/sys/write.2 +++ b/lib/libc/sys/write.2 @@ -134,6 +134,26 @@ and  may write fewer bytes than requested;  the return value must be noted,  and the remainder of the operation should be retried when possible. +.Sh ATOMICITY OF WRITES +When operating on regular files on local file systems, the effects of +.Fn write +are atomic. +As required by the POSIX standard, +the +.Fn read , +.Fn write , +and +.Fn ftruncate +functions and their variations are atomic with respect to +each other on the file data and metadata for regular files. +See for instance +.St -p1003.1-2024 +Volume 2, Section 2.9.7 for more information. +.Pp +.Fx +implements the requirement by taking +a read/write range lock on the file byte range +affected by the corresponding function.  .Sh RETURN VALUES  Upon successful completion the number of bytes which were written  is returned. diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8 index 0adc5ffc228b..1e5440fbc846 100644 --- a/sbin/mount/mount.8 +++ b/sbin/mount/mount.8 @@ -25,7 +25,7 @@  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  .\" SUCH DAMAGE.  .\" -.Dd November 19, 2024 +.Dd October 28, 2025  .Dt MOUNT 8  .Os  .Sh NAME @@ -563,6 +563,7 @@ support for a particular file system might be provided either on a static  .Xr kldload 8 ) .  .Sh SEE ALSO  .Xr getfacl 1 , +.Xr lsvfs 1 ,  .Xr setfacl 1 ,  .Xr nmount 2 ,  .Xr acl 3 , diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3 index aef4944e3847..dd466cf20a0b 100644 --- a/share/man/man3/queue.3 +++ b/share/man/man3/queue.3 @@ -1422,13 +1422,13 @@ while in userland builds it prints the diagnostic message on  .Dv stderr  and then calls  .Fn abort . -These behaviors can be overriden by defining a custom +These behaviors can be overridden by defining a custom  .Fn QMD_PANIC  macro before first inclusion of  .In sys/queue.h .  The diagnostic messages automatically include the source file, line and function -where the failing check occured. -This behavior can be overriden by defining a custom +where the failing check occurred. +This behavior can be overridden by defining a custom  .Fn QMD_ASSERT  macro before first inclusion of  .In sys/queue.h . diff --git a/share/man/man3/siginfo.3 b/share/man/man3/siginfo.3 index f57cf5f7d706..59e3ecf8f3e8 100644 --- a/share/man/man3/siginfo.3 +++ b/share/man/man3/siginfo.3 @@ -224,7 +224,7 @@ raised by a hardware watchpoint exception may report the data address that  triggered the watchpoint in  .Va si_addr .  .Pp -Sychronous signals set +Synchronous signals set  .Va si_trapno  to a machine-dependent trap number.  .Pp diff --git a/share/man/man4/acpi_battery.4 b/share/man/man4/acpi_battery.4 index 3707cd125678..49fed625ea31 100644 --- a/share/man/man4/acpi_battery.4 +++ b/share/man/man4/acpi_battery.4 @@ -158,8 +158,8 @@ Typically this will decrease every charging cycle.  .It btech  Battery technology:  .Bl -tag -width indent -.It 0x00000000 Primary cell Pq non-rechargable -.It 0x00000001 Secondary cell Pq rechargable +.It 0x00000000 Primary cell Pq non-rechargeable +.It 0x00000001 Secondary cell Pq rechargeable  .El  .It Va dvol  Design voltage in mV, diff --git a/share/man/man4/bce.4 b/share/man/man4/bce.4 index ab979f371b66..aab9eaebd505 100644 --- a/share/man/man4/bce.4 +++ b/share/man/man4/bce.4 @@ -240,7 +240,7 @@ Values from 0-256 are valid.  A value of 0 disables this status block update (default 6).  .It Va hw.bce.tx_ticks  Time in microsecond ticks to wait before a status block -update is generated due to TX activitiy. +update is generated due to TX activity.  Values from 0-100 are valid.  A value of 0 disables this status block update.  Cannot be set to 0 if hw.bce.tx_quick_cons_trip is also 0 diff --git a/share/man/man4/iwlwifi.4 b/share/man/man4/iwlwifi.4 index 4a251f239a55..05a0ee6ecacf 100644 --- a/share/man/man4/iwlwifi.4 +++ b/share/man/man4/iwlwifi.4 @@ -284,7 +284,7 @@ module parameters and are mapped automatically by  .Sy linuxkpi .  They were not adjusted so that they stay consistent with upstream  Linux, e.g., for documentation available and problem investigations. -This left their names inconsistent between themselves and incosistent to +This left their names inconsistent between themselves and inconsistent to  .Fx  style.  .Pp diff --git a/share/man/man4/mac_do.4 b/share/man/man4/mac_do.4 index 39bfafd95474..d02932070e25 100644 --- a/share/man/man4/mac_do.4 +++ b/share/man/man4/mac_do.4 @@ -246,7 +246,7 @@ nor contradictory ones.  In practice, no two clauses may display the same ID except for group IDs but  only if, each time the same ID appears, it does so with a different flag, or no  flags only once. -Additionally, the specified flags in multiple occurences must not be +Additionally, the specified flags in multiple occurrences must not be  contradictory.  For example, the same group ID appearing with both  .Ql + diff --git a/share/man/man4/p9fs.4 b/share/man/man4/p9fs.4 index 04f27abd2545..a49053d461d4 100644 --- a/share/man/man4/p9fs.4 +++ b/share/man/man4/p9fs.4 @@ -96,7 +96,7 @@ may not work correctly.  If  .Nm  is the root filesystem, -it is recommented to use with +it is recommended to use with  .Xr tmpfs 5  to ensure that temporary files created in  .Pa /tmp diff --git a/share/man/man4/rights.4 b/share/man/man4/rights.4 index 2d44a1060006..6669f75e1674 100644 --- a/share/man/man4/rights.4 +++ b/share/man/man4/rights.4 @@ -276,7 +276,8 @@ Permit  and  .Xr openat 2  with -.Dv O_FSYNC +.Dv O_DSYNC , +.Dv O_FSYNC ,  or  .Dv O_SYNC  flag. diff --git a/share/man/man7/stats.7 b/share/man/man7/stats.7 index 715db70e118b..0b57d525522c 100644 --- a/share/man/man7/stats.7 +++ b/share/man/man7/stats.7 @@ -24,7 +24,7 @@  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  .\" SUCH DAMAGE.  .\" -.Dd April 22, 2021 +.Dd October 28, 2025  .Dt STATS 7  .Os  .Sh NAME @@ -100,6 +100,7 @@ Report ZFS I/O statistics  .Xr stat 1 ,  .Xr systat 1 ,  .Xr intro 7 , +.Xr tuning 7 ,  .Xr ctlstat 8 ,  .Xr gstat 8 ,  .Xr ibstat 8 , diff --git a/share/man/man7/tuning.7 b/share/man/man7/tuning.7 index f04500d0f0dc..8da4b55b9d4f 100644 --- a/share/man/man7/tuning.7 +++ b/share/man/man7/tuning.7 @@ -22,7 +22,7 @@  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  .\" SUCH DAMAGE.  .\" -.Dd November 17, 2023 +.Dd October 28, 2025  .Dt TUNING 7  .Os  .Sh NAME @@ -702,6 +702,7 @@ over services you export from your box (web services, email).  .Xr firewall 7 ,  .Xr hier 7 ,  .Xr ports 7 , +.Xr stats 7 ,  .Xr boot 8 ,  .Xr bsdinstall 8 ,  .Xr ccdconfig 8 , diff --git a/share/man/man9/insmntque.9 b/share/man/man9/insmntque.9 index 869d8767632b..33ba697b10b9 100644 --- a/share/man/man9/insmntque.9 +++ b/share/man/man9/insmntque.9 @@ -24,7 +24,7 @@  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  .\" DAMAGE.  .\" -.Dd January 29, 2022 +.Dd October 24, 2025  .Dt INSMNTQUE 9  .Os  .Sh NAME @@ -56,7 +56,7 @@ The vnode must be exclusively locked.  .Pp  On failure,  .Fn insmntque -resets vnode' operation vector to the vector of +resets vnode's operations vector to the vector of  .Xr deadfs 9 ,  clears  .Va v_data , @@ -71,7 +71,7 @@ failure is needed, the  function may be used instead.  It does not do any cleanup following a failure, leaving all  the work to the caller. -In particular, the operation vector +In particular, the operations vector  .Va v_op  and  .Va v_data diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index 94455bbde628..d36c64259569 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -479,9 +479,9 @@ FreeBSD 5.2           |      |                 |                       |   |     |              |      |                    |            DragonFly 6.4.1   |     |              |      |                    |            DragonFly 6.4.2   |  FreeBSD           |      |                    |                    | - |   14.3             |      |                    |                    | + |   14.3             |      |                OpenBSD 7.8              |   |                    |      |                    |                    | -FreeBSD 15 -current   |  NetBSD -current   OpenBSD -current    DragonFly -current +FreeBSD 16 -current   |  NetBSD -current   OpenBSD -current    DragonFly -current   |                    |      |                    |                    |   v                    v      v                    v                    v @@ -926,6 +926,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  ------------------------ @@ -981,6 +982,15 @@ URL: https://web.archive.org/web/20090427195917/http://ezine.daemonnews.org/2001  ("what are the differences between FreeBSD, NetBSD, and OpenBSD?") +End-of-Life (EOL) +----------------- +The FreeBSD family tree shows when a release was published. +If you would like to know when the support ends, just look at +https://www.freebsd.org/security/#sup and +https://www.freebsd.org/security/unsupported +For other operating systems, see https://endoflife.date + +  Acknowledgments  --------------- @@ -990,5 +1000,5 @@ original BSD announcements from Usenet or tapes.  Steven M. Schultz for providing 2.8BSD, 2.10BSD, 2.11BSD manual pages.  -- -Copyright (c) 1997-2024 Wolfram Schneider <wosch@FreeBSD.org> +Copyright (c) 1997-2025 Wolfram Schneider <wosch@FreeBSD.org>  URL: https://cgit.freebsd.org/src/tree/share/misc/bsd-family-tree diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index fa15370a82c6..1c32a442aac9 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -49,9 +49,11 @@ CXXFLAGS+= -mretpoline  LDFLAGS+= -Wl,-zretpolineplt  .endif  .else +.if !defined(_NO_INCLUDE_COMPILERMK)  .warning Retpoline requested but not supported by compiler or linker  .endif  .endif +.endif  # LLD sensibly defaults to -znoexecstack, so do the same for BFD  LDFLAGS.bfd+= -Wl,-znoexecstack @@ -65,16 +67,20 @@ CFLAGS+= -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clan  CXXFLAGS+= -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang  .endif  .else +.if !defined(_NO_INCLUDE_COMPILERMK)  .warning InitAll (zeros) requested but not supported by compiler  .endif +.endif  .elif ${MK_INIT_ALL_PATTERN} == "yes"  .if ${COMPILER_FEATURES:Minit-all}  CFLAGS+= -ftrivial-auto-var-init=pattern  CXXFLAGS+= -ftrivial-auto-var-init=pattern  .else +.if !defined(_NO_INCLUDE_COMPILERMK)  .warning InitAll (pattern) requested but not supported by compiler  .endif  .endif +.endif  # bsd.sanitizer.mk is not installed, so don't require it (e.g. for ports).  .sinclude "bsd.sanitizer.mk" diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h index 893979025f01..ba1c8a16fad1 100644 --- a/sys/dev/e1000/e1000_osdep.h +++ b/sys/dev/e1000/e1000_osdep.h @@ -152,6 +152,9 @@ struct e1000_osdep  {  	bus_space_tag_t    mem_bus_space_tag;  	bus_space_handle_t mem_bus_space_handle; +#ifdef INVARIANTS +	bus_size_t	   mem_bus_space_size; +#endif  	bus_space_tag_t    io_bus_space_tag;  	bus_space_handle_t io_bus_space_handle;  	bus_space_tag_t    flash_bus_space_tag; @@ -175,27 +178,44 @@ struct e1000_osdep      bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \      ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset, value) +static __inline uint32_t +e1000_rd32(struct e1000_osdep *osdep, uint32_t reg) +{ + +	KASSERT(reg < osdep->mem_bus_space_size, +	    ("e1000: register offset %#jx too large (max is %#jx)", +	    (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size)); + +	return (bus_space_read_4(osdep->mem_bus_space_tag, +	    osdep->mem_bus_space_handle, reg)); +} + + +static __inline void +e1000_wr32(struct e1000_osdep *osdep, uint32_t reg, uint32_t value) +{ + +	KASSERT(reg < osdep->mem_bus_space_size, +	    ("e1000: register offset %#jx too large (max is %#jx)", +	    (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size)); + +	bus_space_write_4(osdep->mem_bus_space_tag, +	    osdep->mem_bus_space_handle, reg, value); +} +  /* Register READ/WRITE macros */ -#define E1000_READ_REG(hw, reg) \ -    bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ -        ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ -        E1000_REGISTER(hw, reg)) +#define E1000_READ_REG(hw, reg)	\ +	e1000_rd32((hw)->back, E1000_REGISTER(hw, reg))  #define E1000_WRITE_REG(hw, reg, value) \ -    bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ -        ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ -        E1000_REGISTER(hw, reg), value) +	e1000_wr32((hw)->back, E1000_REGISTER(hw, reg), value)  #define E1000_READ_REG_ARRAY(hw, reg, index) \ -    bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ -        ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ -        E1000_REGISTER(hw, reg) + ((index)<< 2)) +        e1000_rd32((hw)->back, E1000_REGISTER(hw, reg) + ((index) << 2))  #define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \ -    bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ -        ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ -        E1000_REGISTER(hw, reg) + ((index)<< 2), value) +        e1000_wr32((hw)->back, E1000_REGISTER(hw, reg) + ((index) << 2), value)  #define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY  #define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index f0ef6051fab1..9040949b36c7 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1575,7 +1575,7 @@ em_if_init(if_ctx_t ctx)  	E1000_WRITE_REG(&sc->hw, E1000_VET, ETHERTYPE_VLAN);  	/* Clear bad data from Rx FIFOs */ -	if (sc->hw.mac.type >= igb_mac_min) +	if (sc->hw.mac.type >= igb_mac_min && !sc->vf_ifp)  		e1000_rx_fifo_flush_base(&sc->hw);  	/* Configure for OS presence */ @@ -1595,7 +1595,9 @@ em_if_init(if_ctx_t ctx)  	/* Don't lose promiscuous settings */  	em_if_set_promisc(ctx, if_getflags(ifp)); -	e1000_clear_hw_cntrs_base_generic(&sc->hw); + +	if (sc->hw.mac.ops.clear_hw_cntrs != NULL) +		sc->hw.mac.ops.clear_hw_cntrs(&sc->hw);  	/* MSI-X configuration for 82574 */  	if (sc->hw.mac.type == e1000_82574) { @@ -2374,7 +2376,7 @@ em_if_stop(if_ctx_t ctx)  		em_flush_desc_rings(sc);  	e1000_reset_hw(&sc->hw); -	if (sc->hw.mac.type >= e1000_82544) +	if (sc->hw.mac.type >= e1000_82544 && !sc->vf_ifp)  		E1000_WRITE_REG(&sc->hw, E1000_WUFC, 0);  	e1000_led_off(&sc->hw); @@ -2433,6 +2435,9 @@ em_allocate_pci_resources(if_ctx_t ctx)  	}  	sc->osdep.mem_bus_space_tag = rman_get_bustag(sc->memory);  	sc->osdep.mem_bus_space_handle = rman_get_bushandle(sc->memory); +#ifdef INVARIANTS +	sc->osdep.mem_bus_space_size = rman_get_size(sc->memory); +#endif  	sc->hw.hw_addr = (u8 *)&sc->osdep.mem_bus_space_handle;  	/* Only older adapters use IO mapping */ @@ -3284,11 +3289,13 @@ em_reset(if_ctx_t ctx)  	/* Issue a global reset */  	e1000_reset_hw(hw); -	if (hw->mac.type >= igb_mac_min) { -		E1000_WRITE_REG(hw, E1000_WUC, 0); -	} else { -		E1000_WRITE_REG(hw, E1000_WUFC, 0); -		em_disable_aspm(sc); +	if (!sc->vf_ifp) { +		if (hw->mac.type >= igb_mac_min) { +			E1000_WRITE_REG(hw, E1000_WUC, 0); +		} else { +			E1000_WRITE_REG(hw, E1000_WUFC, 0); +			em_disable_aspm(sc); +		}  	}  	if (sc->flags & IGB_MEDIA_RESET) {  		e1000_setup_init_funcs(hw, true); @@ -3838,7 +3845,7 @@ em_initialize_receive_unit(if_ctx_t ctx)  			    sc->rx_int_delay.value);  	} -	if (hw->mac.type >= em_mac_min) { +	if (hw->mac.type >= em_mac_min && !sc->vf_ifp) {  		uint32_t rfctl;  		/* Use extended rx descriptor formats */  		rfctl = E1000_READ_REG(hw, E1000_RFCTL); @@ -3858,33 +3865,38 @@ em_initialize_receive_unit(if_ctx_t ctx)  		E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);  	} -	/* Set up L3 and L4 csum Rx descriptor offloads */ -	rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); -	if (if_getcapenable(ifp) & IFCAP_RXCSUM) { -		rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL; -		if (hw->mac.type > e1000_82575) -			rxcsum |= E1000_RXCSUM_CRCOFL; -		else if (hw->mac.type < em_mac_min && -		    if_getcapenable(ifp) & IFCAP_HWCSUM_IPV6) -			rxcsum |= E1000_RXCSUM_IPV6OFL; -	} else { -		rxcsum &= ~(E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); -		if (hw->mac.type > e1000_82575) -			rxcsum &= ~E1000_RXCSUM_CRCOFL; -		else if (hw->mac.type < em_mac_min) -			rxcsum &= ~E1000_RXCSUM_IPV6OFL; -	} +	/* +	 * Set up L3 and L4 csum Rx descriptor offloads only on Physical +	 * Functions. Virtual Functions have no access to this register. +	 */ +	if (!sc->vf_ifp) { +		rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); +		if (if_getcapenable(ifp) & IFCAP_RXCSUM) { +			rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL; +			if (hw->mac.type > e1000_82575) +				rxcsum |= E1000_RXCSUM_CRCOFL; +			else if (hw->mac.type < em_mac_min && +			    if_getcapenable(ifp) & IFCAP_HWCSUM_IPV6) +				rxcsum |= E1000_RXCSUM_IPV6OFL; +		} else { +			rxcsum &= ~(E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); +			if (hw->mac.type > e1000_82575) +				rxcsum &= ~E1000_RXCSUM_CRCOFL; +			else if (hw->mac.type < em_mac_min) +				rxcsum &= ~E1000_RXCSUM_IPV6OFL; +		} -	if (sc->rx_num_queues > 1) { -		/* RSS hash needed in the Rx descriptor */ -		rxcsum |= E1000_RXCSUM_PCSD; +		if (sc->rx_num_queues > 1) { +			/* RSS hash needed in the Rx descriptor */ +			rxcsum |= E1000_RXCSUM_PCSD; -		if (hw->mac.type >= igb_mac_min) -			igb_initialize_rss_mapping(sc); -		else -			em_initialize_rss_mapping(sc); +			if (hw->mac.type >= igb_mac_min) +				igb_initialize_rss_mapping(sc); +			else +				em_initialize_rss_mapping(sc); +		} +		E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);  	} -	E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);  	for (i = 0, que = sc->rx_queues; i < sc->rx_num_queues; i++, que++) {  		struct rx_ring *rxr = &que->rxr; @@ -4392,6 +4404,8 @@ em_get_wakeup(if_ctx_t ctx)  	switch (sc->hw.mac.type) {  	case e1000_82542:  	case e1000_82543: +	case e1000_vfadapt: +	case e1000_vfadapt_i350:  		break;  	case e1000_82544:  		e1000_read_nvm(&sc->hw, @@ -4437,8 +4451,6 @@ em_get_wakeup(if_ctx_t ctx)  	case e1000_i354:  	case e1000_i210:  	case e1000_i211: -	case e1000_vfadapt: -	case e1000_vfadapt_i350:  		apme_mask = E1000_WUC_APME;  		sc->has_amt = true;  		eeprom_data = E1000_READ_REG(&sc->hw, E1000_WUC); @@ -4494,7 +4506,6 @@ em_get_wakeup(if_ctx_t ctx)  			global_quad_port_a = 0;  		break;  	} -	return;  } diff --git a/sys/dev/ice/ice_drv_info.h b/sys/dev/ice/ice_drv_info.h index 46965f4124bc..abb11bdb5fd9 100644 --- a/sys/dev/ice/ice_drv_info.h +++ b/sys/dev/ice/ice_drv_info.h @@ -238,6 +238,9 @@ static const pci_vendor_info_t ice_vendor_info_array[] = {  		  ICE_INTEL_VENDOR_ID, 0x0001, 0,  		  "Intel(R) Ethernet Network Adapter E835-XXV-2 for OCP 3.0"),  	PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP, +		  ICE_INTEL_VENDOR_ID, 0x0002, 0, +		  "Intel(R) Ethernet Network Adapter E835-XXV-4"), +	PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP,  		  ICE_INTEL_VENDOR_ID, 0x0003, 0,  		  "Intel(R) Ethernet Network Adapter E835-XXV-2"),  	PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP, diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 43c3af056b67..aa2e69ea0b5a 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -1480,17 +1480,33 @@ ixl_if_multi_set(if_ctx_t ctx)  	struct ixl_pf *pf = iflib_get_softc(ctx);  	struct ixl_vsi *vsi = &pf->vsi;  	struct i40e_hw *hw = vsi->hw; +	enum i40e_status_code status;  	int mcnt; +	if_t ifp = iflib_get_ifp(ctx);  	IOCTL_DEBUGOUT("ixl_if_multi_set: begin");  	/* Delete filters for removed multicast addresses */  	ixl_del_multi(vsi, false); -	mcnt = min(if_llmaddr_count(iflib_get_ifp(ctx)), MAX_MULTICAST_ADDR); +	mcnt = min(if_llmaddr_count(ifp), MAX_MULTICAST_ADDR);  	if (__predict_false(mcnt == MAX_MULTICAST_ADDR)) { -		i40e_aq_set_vsi_multicast_promiscuous(hw, +		/* Check if promisc mode is already enabled, if yes return */ +		if (vsi->flags & IXL_FLAGS_MC_PROMISC) +			return; + +		status = i40e_aq_set_vsi_multicast_promiscuous(hw,  		    vsi->seid, TRUE, NULL); +		if (status != I40E_SUCCESS) +			if_printf(ifp, "Failed to enable multicast promiscuous " +			    "mode, status: %s\n", i40e_stat_str(hw, status)); +		else { +			if_printf(ifp, "Enabled multicast promiscuous mode\n"); + +			/* Set the flag to track promiscuous mode */ +			vsi->flags |= IXL_FLAGS_MC_PROMISC; +		} +		/* Delete all existing MC filters */  		ixl_del_multi(vsi, true);  		return;  	} @@ -1693,6 +1709,13 @@ ixl_if_promisc_set(if_ctx_t ctx, int flags)  		return (err);  	err = i40e_aq_set_vsi_multicast_promiscuous(hw,  	    vsi->seid, multi, NULL); + +	/* Update the multicast promiscuous flag based on the new state */ +	if (multi) +		vsi->flags |= IXL_FLAGS_MC_PROMISC; +	else +		vsi->flags &= ~IXL_FLAGS_MC_PROMISC; +  	return (err);  } diff --git a/sys/dev/ixl/ixl.h b/sys/dev/ixl/ixl.h index f45354d29300..69925a131b35 100644 --- a/sys/dev/ixl/ixl.h +++ b/sys/dev/ixl/ixl.h @@ -202,6 +202,7 @@  #define IXL_FLAGS_KEEP_TSO6	(1 << 1)  #define IXL_FLAGS_USES_MSIX	(1 << 2)  #define IXL_FLAGS_IS_VF		(1 << 3) +#define IXL_FLAGS_MC_PROMISC	(1 << 4)  #define IXL_VSI_IS_PF(v)	((v->flags & IXL_FLAGS_IS_VF) == 0)  #define IXL_VSI_IS_VF(v)	((v->flags & IXL_FLAGS_IS_VF) != 0) diff --git a/sys/dev/ixl/ixl_pf_main.c b/sys/dev/ixl/ixl_pf_main.c index 4f384e7191af..99851af61cfe 100644 --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -592,24 +592,29 @@ ixl_add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)   *	Routines for multicast and vlan filter management.   *   *********************************************************************/ + +/** + * ixl_add_multi - Add multicast filters to the hardware + * @vsi: The VSI structure + * + * In case number of multicast filters in the IFP exceeds 127 entries, + * multicast promiscuous mode will be enabled and the filters will be removed + * from the hardware + */  void  ixl_add_multi(struct ixl_vsi *vsi)  {  	if_t			ifp = vsi->ifp; -	struct i40e_hw		*hw = vsi->hw;  	int			mcnt = 0;  	struct ixl_add_maddr_arg cb_arg;  	IOCTL_DEBUGOUT("ixl_add_multi: begin"); -	mcnt = if_llmaddr_count(ifp); -	if (__predict_false(mcnt >= MAX_MULTICAST_ADDR)) { -		i40e_aq_set_vsi_multicast_promiscuous(hw, -		    vsi->seid, TRUE, NULL); -		/* delete all existing MC filters */ -		ixl_del_multi(vsi, true); -		return; -	} +	/* +	 * There is no need to check if the number of multicast addresses +	 * exceeds the MAX_MULTICAST_ADDR threshold and set promiscuous mode +	 * here, as all callers already handle this case. +	 */  	cb_arg.vsi = vsi;  	LIST_INIT(&cb_arg.to_add); @@ -632,30 +637,103 @@ ixl_match_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)  		return (0);  } +/** + * ixl_dis_multi_promisc - Disable multicast promiscuous mode + * @vsi: The VSI structure + * @vsi_mcnt: Number of multicast filters in the VSI + * + * Disable multicast promiscuous mode based on number of entries in the IFP + * and the VSI, then re-add multicast filters. + * + */ +static void +ixl_dis_multi_promisc(struct ixl_vsi *vsi, int vsi_mcnt) +{ +	struct ifnet		*ifp = vsi->ifp; +	struct i40e_hw		*hw = vsi->hw; +	int			ifp_mcnt = 0; +	enum i40e_status_code	status; + +	/* +	 * Check if multicast promiscuous mode was actually enabled. +	 * If promiscuous mode was not enabled, don't attempt to disable it. +	 * Also, don't disable if IFF_PROMISC or IFF_ALLMULTI is set. +	 */ +	if (!(vsi->flags & IXL_FLAGS_MC_PROMISC) || +	    (if_getflags(ifp) & (IFF_PROMISC | IFF_ALLMULTI))) +		return; + +	ifp_mcnt = if_llmaddr_count(ifp); +	/* +	 * Equal lists or empty ifp list mean the list has not been changed +	 * and in such case avoid disabling multicast promiscuous mode as it +	 * was not previously enabled. Case where multicast promiscuous mode has +	 * been enabled is when vsi_mcnt == 0 && ifp_mcnt > 0. +	 */ +	if (ifp_mcnt == vsi_mcnt || ifp_mcnt == 0 || +	    ifp_mcnt >= MAX_MULTICAST_ADDR) +		return; + +	status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, +	    FALSE, NULL); +	if (status != I40E_SUCCESS) { +		if_printf(ifp, "Failed to disable multicast promiscuous " +		    "mode, status: %s\n", i40e_stat_str(hw, status)); + +		return; +	} + +	/* Clear the flag since promiscuous mode is now disabled */ +	vsi->flags &= ~IXL_FLAGS_MC_PROMISC; +	if_printf(ifp, "Disabled multicast promiscuous mode\n"); + +	ixl_add_multi(vsi); +} + +/** + * ixl_del_multi - Delete multicast filters from the hardware + * @vsi: The VSI structure + * @all: Bool to determine if all the multicast filters should be removed + * + * In case number of multicast filters in the IFP drops to 127 entries, + * multicast promiscuous mode will be disabled and the filters will be reapplied + * to the hardware. + */  void  ixl_del_multi(struct ixl_vsi *vsi, bool all)  { -	struct ixl_ftl_head	to_del; +	int			to_del_cnt = 0, vsi_mcnt = 0;  	if_t			ifp = vsi->ifp;  	struct ixl_mac_filter	*f, *fn; -	int			mcnt = 0; +	struct ixl_ftl_head	to_del;  	IOCTL_DEBUGOUT("ixl_del_multi: begin");  	LIST_INIT(&to_del);  	/* Search for removed multicast addresses */  	LIST_FOREACH_SAFE(f, &vsi->ftl, ftle, fn) { -		if ((f->flags & IXL_FILTER_MC) == 0 || -		    (!all && (if_foreach_llmaddr(ifp, ixl_match_maddr, f) == 0))) +		if ((f->flags & IXL_FILTER_MC) == 0) +			continue; + +		/* Count all the multicast filters in the VSI for comparison */ +		vsi_mcnt++; + +		if (!all && if_foreach_llmaddr(ifp, ixl_match_maddr, f) != 0)  			continue;  		LIST_REMOVE(f, ftle);  		LIST_INSERT_HEAD(&to_del, f, ftle); -		mcnt++; +		to_del_cnt++;  	} -	if (mcnt > 0) -		ixl_del_hw_filters(vsi, &to_del, mcnt); +	if (to_del_cnt > 0) { +		ixl_del_hw_filters(vsi, &to_del, to_del_cnt); +		return; +	} + +	ixl_dis_multi_promisc(vsi, vsi_mcnt); + +	IOCTL_DEBUGOUT("ixl_del_multi: end");  }  void diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index c5483623a9a5..387c5465618a 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -5157,7 +5157,7 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred,  	struct nfsrv_descript nfsd;  	struct nfsrv_descript *nd = &nfsd;  	u_char *cp, *cp2, *fhp; -	int error, cnt, len, setnil; +	int error, cnt, i, len, setnil;  	u_int32_t *opcntp;  	nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL, 0, @@ -5198,8 +5198,12 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred,  	if (error)  		return (error);  	if (nd->nd_repstat == 0) { -		NFSM_DISSECT(tl, u_int32_t *, (3 + 2 * cnt) * NFSX_UNSIGNED); -		tl += (2 + 2 * cnt); +		NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED); +		tl += 2; +		for (i = 0; i < cnt; i++) { +			NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); +			tl++; +		}  		if ((len = fxdr_unsigned(int, *tl)) <= 0 ||  			len > NFSX_FHMAX) {  			nd->nd_repstat = NFSERR_BADXDR; diff --git a/sys/geom/zero/g_zero.c b/sys/geom/zero/g_zero.c index 66cc884fab56..be31cc794cb5 100644 --- a/sys/geom/zero/g_zero.c +++ b/sys/geom/zero/g_zero.c @@ -47,11 +47,11 @@ static SYSCTL_NODE(_kern_geom, OID_AUTO, zero, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,      "GEOM_ZERO stuff");  static int g_zero_clear = 1;  SYSCTL_PROC(_kern_geom_zero, OID_AUTO, clear, -    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &g_zero_clear, 0, +    CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &g_zero_clear, 0,      g_zero_clear_sysctl, "I",      "Clear read data buffer");  static int g_zero_byte = 0; -SYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RW, &g_zero_byte, 0, +SYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RWTUN, &g_zero_byte, 0,      "Byte (octet) value to clear the buffers with");  static struct g_provider *gpp; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 9c5c5b9dfa80..99f9e129f4cd 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1074,7 +1074,7 @@ flags_to_rights(int flags, cap_rights_t *rightsp)  	if (flags & O_TRUNC)  		cap_rights_set_one(rightsp, CAP_FTRUNCATE); -	if (flags & (O_SYNC | O_FSYNC)) +	if (flags & (O_SYNC | O_FSYNC | O_DSYNC))  		cap_rights_set_one(rightsp, CAP_FSYNC);  	if (flags & (O_EXLOCK | O_SHLOCK)) diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index e534fdd77635..129dc1cfe892 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -110,6 +110,8 @@ SYSCTL_NODE(_net_inet, IPPROTO_ICMP, icmp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,      "ICMP");  SYSCTL_NODE(_net_inet, IPPROTO_UDP, udp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,      "UDP"); +SYSCTL_NODE(_net_inet, IPPROTO_UDPLITE, udplite, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, +    "UDP-Lite");  SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,      "TCP");  #if defined(SCTP) || defined(SCTP_SUPPORT) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 6829d2a743f2..81b378f496c9 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -654,7 +654,7 @@ tcp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,  		}  	}  	m->m_pkthdr.tcp_tun_port = port = uh->uh_sport; -	bcopy(th, uh, m->m_len - off); +	bcopy(th, uh, m->m_len - off - sizeof(struct udphdr));  	m->m_len -= sizeof(struct udphdr);  	m->m_pkthdr.len -= sizeof(struct udphdr);  	/* diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 077c3a5f6ef3..713f6a35ad45 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1175,7 +1175,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) { @@ -1387,6 +1387,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,  	struct tcpcb *tp;  	struct socket *rv = NULL;  	struct syncache *sc = NULL; +	struct ucred *cred;  	struct syncache_head *sch;  	struct mbuf *ipopts = NULL;  	u_int ltflags; @@ -1415,6 +1416,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,  	 */  	KASSERT(SOLISTENING(so), ("%s: %p not listening", __func__, so));  	tp = sototcpcb(so); +	cred = V_tcp_syncache.see_other ? NULL : crhold(so->so_cred);  #ifdef INET6  	if (inc->inc_flags & INC_ISIPV6) { @@ -1643,16 +1645,16 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,  	/*  	 * sc_cred is only used in syncache_pcblist() to list TCP endpoints in  	 * TCPS_SYN_RECEIVED state when V_tcp_syncache.see_other is false. -	 * Therefore, store the credentials and take a reference count only -	 * when needed: +	 * Therefore, store the credentials only when needed:  	 * - sc is allocated from the zone and not using the on stack instance.  	 * - the sysctl variable net.inet.tcp.syncache.see_other is false.  	 * The reference count is decremented when a zone allocated sc is  	 * freed in syncache_free().  	 */ -	if (sc != &scs && !V_tcp_syncache.see_other) -		sc->sc_cred = crhold(so->so_cred); -	else +	if (sc != &scs && !V_tcp_syncache.see_other) { +		sc->sc_cred = cred; +		cred = NULL; +	} else  		sc->sc_cred = NULL;  	sc->sc_port = port;  	sc->sc_ipopts = ipopts; @@ -1790,6 +1792,8 @@ donenoprobe:  		tcp_fastopen_decrement_counter(tfo_pending);  tfo_expanded: +	if (cred != NULL) +		crfree(cred);  	if (sc == NULL || sc == &scs) {  #ifdef MAC  		mac_syncache_destroy(&maclabel); diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 65a9fbc84ff7..1c687e94bb4a 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -515,9 +515,12 @@ tcp_timer_persist(struct tcpcb *tp)  	if (progdrop || (tp->t_rxtshift >= V_tcp_retries &&  	    (ticks - tp->t_rcvtime >= tcp_maxpersistidle ||  	     ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff))) { -		if (!progdrop) +		if (progdrop) { +			tcp_log_end_status(tp, TCP_EI_STATUS_PROGRESS); +		} else {  			TCPSTAT_INC(tcps_persistdrop); -		tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); +			tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); +		}  		goto dropit;  	}  	/* diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 88df8f8d38fc..a1000dadf583 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -852,6 +852,11 @@ SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist,      udp_pcblist, "S,xinpcb",      "List of active UDP sockets"); +SYSCTL_PROC(_net_inet_udplite, OID_AUTO, pcblist, +    CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, IPPROTO_UDPLITE, +    udp_pcblist, "S,xinpcb", +    "List of active UDP-Lite sockets"); +  #ifdef INET  static int  udp_getcred(SYSCTL_HANDLER_ARGS) @@ -1141,7 +1146,19 @@ udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,  	else  		INP_RLOCK(inp);  	NET_EPOCH_ENTER(et); +#ifdef INET6 +	if ((flags & PRUS_IPV6) != 0) { +		if ((inp->in6p_outputopts != NULL) && +		    (inp->in6p_outputopts->ip6po_tclass != -1)) +			tos = (u_char)inp->in6p_outputopts->ip6po_tclass; +		else +			tos = 0; +	} else { +		tos = inp->inp_ip_tos; +	} +#else  	tos = inp->inp_ip_tos; +#endif  	if (control != NULL) {  		/*  		 * XXX: Currently, we assume all the optional information is @@ -1165,6 +1182,23 @@ udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,  			error = udp_v4mapped_pktinfo(cm, &src, inp, flags);  			if (error != 0)  				break; +			if (((flags & PRUS_IPV6) != 0) && +			    (cm->cmsg_level == IPPROTO_IPV6) && +			    (cm->cmsg_type == IPV6_TCLASS)) { +				int tclass; + +				if (cm->cmsg_len != CMSG_LEN(sizeof(int))) { +					error = EINVAL; +					break; +				} +				tclass = *(int *)CMSG_DATA(cm); +				if (tclass < -1 || tclass > 255) { +					error = EINVAL; +					break; +				} +				if (tclass != -1) +					tos = (u_char)tclass; +			}  #endif  			if (cm->cmsg_level != IPPROTO_IP)  				continue; diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 51272e7c9349..569b7b8d5240 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -141,6 +141,7 @@ void	kmod_udpstat_inc(int statnum);      kmod_udpstat_inc(offsetof(struct udpstat, name) / sizeof(uint64_t))  SYSCTL_DECL(_net_inet_udp); +SYSCTL_DECL(_net_inet_udplite);  VNET_DECLARE(struct inpcbinfo, udbinfo);  VNET_DECLARE(struct inpcbinfo, ulitecbinfo); diff --git a/sys/netpfil/ipfw/pmod/tcpmod.c b/sys/netpfil/ipfw/pmod/tcpmod.c index d7400f4fd5ed..138fefe22a98 100644 --- a/sys/netpfil/ipfw/pmod/tcpmod.c +++ b/sys/netpfil/ipfw/pmod/tcpmod.c @@ -58,7 +58,8 @@ VNET_DEFINE_STATIC(uint16_t, tcpmod_setmss_eid) = 0;  #define	V_tcpmod_setmss_eid	VNET(tcpmod_setmss_eid)  static int -tcpmod_setmss(struct mbuf **mp, struct tcphdr *tcp, int tlen, uint16_t mss) +tcpmod_setmss(struct mbuf **mp, struct tcphdr *tcp, int tlen, uint16_t mss, +    int *done)  {  	struct mbuf *m;  	u_char *cp; @@ -73,8 +74,10 @@ tcpmod_setmss(struct mbuf **mp, struct tcphdr *tcp, int tlen, uint16_t mss)  		 * TCP header with options.  		 */  		*mp = m = m_pullup(m, m->m_pkthdr.len); -		if (m == NULL) +		if (m == NULL) { +			*done = 1;  			return (ret); +		}  	}  	/* Parse TCP options. */  	for (tlen -= sizeof(struct tcphdr), cp = (u_char *)(tcp + 1); @@ -115,7 +118,7 @@ tcpmod_setmss(struct mbuf **mp, struct tcphdr *tcp, int tlen, uint16_t mss)  #ifdef INET6  static int -tcpmod_ipv6_setmss(struct mbuf **mp, uint16_t mss) +tcpmod_ipv6_setmss(struct mbuf **mp, uint16_t mss, int *done)  {  	struct ip6_hdr *ip6;  	struct ip6_hbh *hbh; @@ -143,13 +146,13 @@ tcpmod_ipv6_setmss(struct mbuf **mp, uint16_t mss)  	/* We must have TCP options and enough data in a packet. */  	if (hlen <= sizeof(struct tcphdr) || hlen > plen)  		return (IP_FW_DENY); -	return (tcpmod_setmss(mp, tcp, hlen, mss)); +	return (tcpmod_setmss(mp, tcp, hlen, mss, done));  }  #endif /* INET6 */  #ifdef INET  static int -tcpmod_ipv4_setmss(struct mbuf **mp, uint16_t mss) +tcpmod_ipv4_setmss(struct mbuf **mp, uint16_t mss, int *done)  {  	struct tcphdr *tcp;  	struct ip *ip; @@ -163,7 +166,7 @@ tcpmod_ipv4_setmss(struct mbuf **mp, uint16_t mss)  	/* We must have TCP options and enough data in a packet. */  	if (hlen <= sizeof(struct tcphdr) || hlen > plen)  		return (IP_FW_DENY); -	return (tcpmod_setmss(mp, tcp, hlen, mss)); +	return (tcpmod_setmss(mp, tcp, hlen, mss, done));  }  #endif /* INET */ @@ -207,19 +210,23 @@ ipfw_tcpmod(struct ip_fw_chain *chain, struct ip_fw_args *args,  	switch (args->f_id.addr_type) {  #ifdef INET  		case 4: -			ret = tcpmod_ipv4_setmss(&args->m, htons(icmd->arg1)); +			ret = tcpmod_ipv4_setmss(&args->m, htons(icmd->arg1), +			    done);  			break;  #endif  #ifdef INET6  		case 6: -			ret = tcpmod_ipv6_setmss(&args->m, htons(icmd->arg1)); +			ret = tcpmod_ipv6_setmss(&args->m, htons(icmd->arg1), +			    done);  			break;  #endif  	}  	/*  	 * We return zero in both @ret and @done on success, and ipfw_chk()  	 * will update rule counters. Otherwise a packet will not be matched -	 * by rule. +	 * by rule. We passed @done around above in case we hit a fatal error +	 * somewhere, we'll return non-zero but signal that rule processing +	 * cannot succeed.  	 */  	return (ret);  } diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 8c080b472653..2a5cb0612d36 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -530,6 +530,9 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)  	PF_RULES_RASSERT(); +	if (strnlen(sp->pfs_1301.ifname, IFNAMSIZ) == IFNAMSIZ) +		return (EINVAL); +  	if (sp->pfs_1301.creatorid == 0) {  		if (V_pf_status.debug >= PF_DEBUG_MISC)  			printf("%s: invalid creator id: %08x\n", __func__, diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index d95f36d06ee3..cf53ea638095 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -4645,6 +4645,17 @@ DIOCCHANGEADDR_error:  			error = ENODEV;  			break;  		} +		if (strnlen(io->pfrio_table.pfrt_anchor, MAXPATHLEN) +		    == MAXPATHLEN) { +			error = EINVAL; +			goto fail; +		} +		if (strnlen(io->pfrio_table.pfrt_name, PF_TABLE_NAME_SIZE) +		    == PF_TABLE_NAME_SIZE) { +			error = EINVAL; +			goto fail; +		} +  		PF_RULES_WLOCK();  		error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,  		    io->pfrio_flags | PFR_FLAG_USERIOCTL); diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index 6a913883cc5c..bf05855439bc 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -371,9 +371,12 @@ lvt_mode_impl(struct lapic *la, struct lvt *lvt, u_int pin, uint32_t value)  	case APIC_LVT_DM_SMI:  	case APIC_LVT_DM_INIT:  	case APIC_LVT_DM_EXTINT: -		if (!lvt->lvt_edgetrigger && bootverbose) { -			printf("lapic%u: Forcing LINT%u to edge trigger\n", -			    la->la_id, pin); +		if (!lvt->lvt_edgetrigger) { +			if (bootverbose) { +				printf( +				    "lapic%u: Forcing LINT%u to edge trigger\n", +				    la->la_id, pin); +			}  			value &= ~APIC_LVT_TM;  		}  		/* Use a vector of 0. */ diff --git a/tests/sys/netpfil/pf/ioctl/validation.c b/tests/sys/netpfil/pf/ioctl/validation.c index 1ce8999dcb91..651e6837acd7 100644 --- a/tests/sys/netpfil/pf/ioctl/validation.c +++ b/tests/sys/netpfil/pf/ioctl/validation.c @@ -32,6 +32,7 @@  #include <net/if.h>  #include <net/pfvar.h> +#include <errno.h>  #include <fcntl.h>  #include <stdio.h> @@ -192,6 +193,38 @@ ATF_TC_CLEANUP(gettables, tc)  	COMMON_CLEANUP();  } +ATF_TC_WITH_CLEANUP(clrtables); +ATF_TC_HEAD(clrtables, tc) +{ +	atf_tc_set_md_var(tc, "require.user", "root"); +	atf_tc_set_md_var(tc, "require.kmods", "pf"); +} + +ATF_TC_BODY(clrtables, tc) +{ +	struct pfioc_table io; +	struct pfr_table tbl; +	int flags; + +	COMMON_HEAD(); + +	flags = 0; + +	memset(&io, '/', sizeof(io)); +	io.pfrio_flags = flags; +	io.pfrio_buffer = &tbl; +	io.pfrio_esize = 0; +	io.pfrio_size = 1; + +	if (ioctl(dev, DIOCRCLRTABLES, &io) == 0) +		atf_tc_fail("Request with unterminated anchor name succeeded"); +} + +ATF_TC_CLEANUP(clrtables, tc) +{ +	COMMON_CLEANUP(); +} +  ATF_TC_WITH_CLEANUP(gettstats);  ATF_TC_HEAD(gettstats, tc)  { @@ -894,11 +927,36 @@ ATF_TC_CLEANUP(rpool_mtx2, tc)  } +ATF_TC_WITH_CLEANUP(addstate); +ATF_TC_HEAD(addstate, tc) +{ +	atf_tc_set_md_var(tc, "require.user", "root"); +	atf_tc_set_md_var(tc, "require.kmods", "pfsync"); +} + +ATF_TC_BODY(addstate, tc) +{ +	struct pfioc_state st; + +	COMMON_HEAD(); + +	memset(&st, 'a', sizeof(st)); +	st.state.timeout = PFTM_TCP_FIRST_PACKET; + +	ATF_CHECK_ERRNO(EINVAL, ioctl(dev, DIOCADDSTATE, &st) == -1); +} + +ATF_TC_CLEANUP(addstate, tc) +{ +	COMMON_CLEANUP(); +} +  ATF_TP_ADD_TCS(tp)  {  	ATF_TP_ADD_TC(tp, addtables);  	ATF_TP_ADD_TC(tp, deltables);  	ATF_TP_ADD_TC(tp, gettables); +	ATF_TP_ADD_TC(tp, clrtables);  	ATF_TP_ADD_TC(tp, getastats);  	ATF_TP_ADD_TC(tp, gettstats);  	ATF_TP_ADD_TC(tp, clrtstats); @@ -918,6 +976,7 @@ ATF_TP_ADD_TCS(tp)  	ATF_TP_ADD_TC(tp, tag);  	ATF_TP_ADD_TC(tp, rpool_mtx);  	ATF_TP_ADD_TC(tp, rpool_mtx2); +	ATF_TP_ADD_TC(tp, addstate);  	return (atf_no_error());  } diff --git a/usr.bin/bsdcat/Makefile b/usr.bin/bsdcat/Makefile index 8e730e634ea6..0377a4c48f5f 100644 --- a/usr.bin/bsdcat/Makefile +++ b/usr.bin/bsdcat/Makefile @@ -12,7 +12,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 b52c9645ebb5..a52a12ea361b 100644 --- a/usr.bin/cpio/Makefile +++ b/usr.bin/cpio/Makefile @@ -12,7 +12,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 d99b1c37e226..e06f7fc34de3 100644 --- a/usr.bin/cpio/tests/Makefile +++ b/usr.bin/cpio/tests/Makefile @@ -27,7 +27,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/netstat/inet.c b/usr.bin/netstat/inet.c index 363224d5f913..898158ce288a 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -90,7 +90,7 @@ static void inetprint(const char *, struct in_addr *, int, const char *, int,      const int);  #endif  #ifdef INET6 -static int udp_done, tcp_done, sdp_done; +static int udp_done, udplite_done, tcp_done, sdp_done;  #endif /* INET6 */  static int @@ -107,6 +107,9 @@ pcblist_sysctl(int proto, const char *name, char **bufp)  	case IPPROTO_UDP:  		mibvar = "net.inet.udp.pcblist";  		break; +	case IPPROTO_UDPLITE: +		mibvar = "net.inet.udplite.pcblist"; +		break;  	default:  		mibvar = "net.inet.raw.pcblist";  		break; @@ -229,11 +232,18 @@ protopr(u_long off, const char *name, int af1, int proto)  			udp_done = 1;  #endif  		break; +	case IPPROTO_UDPLITE: +#ifdef INET6 +		if (udplite_done != 0) +			return; +		else +			udplite_done = 1; +#endif +		break;  	}  	if (!pcblist_sysctl(proto, name, &buf))  		return; -  	if (istcp && (cflag || Cflag)) {  		fnamelen = strlen("Stack");  		cnamelen = strlen("CC"); @@ -325,18 +335,18 @@ protopr(u_long off, const char *name, int af1, int proto)  				    "Proto", "Listen", "Local Address");  			else if (Tflag)  				xo_emit((Aflag && !Wflag) ? -    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%s}" : +    "{T:/%-9.9s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%s}" :  				    ((!Wflag || af1 == AF_INET) ? -    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%s}" : -    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%s}"), +    "{T:/%-9.9s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%s}" : +    "{T:/%-9.9s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%s}"),  				    "Proto", "Rexmit", "OOORcv", "0-win",  				    "Local Address", "Foreign Address");  			else {  				xo_emit((Aflag && !Wflag) ? -    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" : +    "{T:/%-9.9s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" :  				    ((!Wflag || af1 == AF_INET) ? -    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}" : -    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%-45.45s}"), +    "{T:/%-9.9s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}" : +    "{T:/%-9.9s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%-45.45s}"),  				    "Proto", "Recv-Q", "Send-Q",  				    "Local Address", "Foreign Address");  				if (!xflag && !Rflag) @@ -389,9 +399,14 @@ protopr(u_long off, const char *name, int af1, int proto)  		vchar = ((inp->inp_vflag & INP_IPV4) != 0) ?  		    "4" : "";  		if (istcp && (tp->t_flags & TF_TOE) != 0) -			xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", "toe", vchar); -		else -			xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", name, vchar); +			xo_emit("{:protocol/%-3.3s%-6.6s/%s%s} ", "toe", vchar); +		else { +			int len; + +			len = max (2, 9 - strlen(name)); +			xo_emit("{:protocol/%.7s%-*.*s/%s%s} ", name, len, len, +			    vchar); +		}  		if (Lflag) {  			char buf1[33]; diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 481284cb88a6..a60d951c8d39 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -96,6 +96,8 @@ static struct protox {  	  tcp_stats,	NULL,		"tcp",	1,	IPPROTO_TCP },  	{ -1	,	N_UDPSTAT,	1,	protopr,  	  udp_stats,	NULL,		"udp",	1,	IPPROTO_UDP }, +	{ -1,		-1,		1,	protopr, +	  NULL,		NULL,		"udplite", 1,	IPPROTO_UDPLITE },  #ifdef SCTP  	{ -1,		N_SCTPSTAT,	1,	sctp_protopr,  	  sctp_stats,	NULL,		"sctp",	1,	IPPROTO_SCTP }, @@ -142,6 +144,8 @@ static struct protox ip6protox[] = {  	  tcp_stats,	NULL,		"tcp",	1,	IPPROTO_TCP },  	{ -1	,	N_UDPSTAT,	1,	protopr,  	  udp_stats,	NULL,		"udp",	1,	IPPROTO_UDP }, +	{ -1,		-1,		1,	protopr, +	  NULL,		NULL,		"udplite", 1,	IPPROTO_UDPLITE },  	{ -1	,	N_IP6STAT,	1,	protopr,  	  ip6_stats,	ip6_ifstats,	"ip6",	1,	IPPROTO_RAW },  	{ -1	,	N_ICMP6STAT,	1,	protopr, diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1 index eba4b1c4aed5..abd83f049703 100644 --- a/usr.bin/sockstat/sockstat.1 +++ b/usr.bin/sockstat/sockstat.1 @@ -25,7 +25,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 October 7, 2025 +.Dd October 9, 2025  .Dt SOCKSTAT 1  .Os  .Sh NAME @@ -194,6 +194,7 @@ is specified (only for SCTP or TCP).  The path state if  .Fl s  is specified (only for SCTP). +This column is only shown when there is at least one path state to show.  .It Li CONN STATE  The connection state if  .Fl s diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index 4548eb8a0b11..587647e5950f 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -99,11 +99,13 @@ static int	 opt_U;		/* Show remote UDP encapsulation port number */  static int	 opt_u;		/* Show Unix domain sockets */  static int	 opt_v;		/* Verbose mode */  static int	 opt_w;		/* Wide print area for addresses */ +static bool	 show_path_state = false;  /*   * Default protocols to use if no -P was defined.   */ -static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" }; +static const char *default_protos[] = {"sctp", "tcp", "udp", "udplite", +    "divert" };  static size_t	   default_numprotos = nitems(default_protos);  static int	*protos;	/* protocols to use */ @@ -519,6 +521,7 @@ gather_sctp(void)  				    ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||  				     (xstcb->last == 1))) {  					RB_INSERT(socks_t, &socks, sock); +					show_path_state = true;  				} else {  					free_socket(sock);  				} @@ -684,6 +687,10 @@ gather_inet(int proto)  		varname = "net.inet.udp.pcblist";  		protoname = "udp";  		break; +	case IPPROTO_UDPLITE: +		varname = "net.inet.udplite.pcblist"; +		protoname = "udplite"; +		break;  	case IPPROTO_DIVERT:  		varname = "net.inet.divert.pcblist";  		protoname = "div"; @@ -732,6 +739,7 @@ gather_inet(int proto)  			protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";  			break;  		case IPPROTO_UDP: +		case IPPROTO_UDPLITE:  		case IPPROTO_DIVERT:  			xip = (struct xinpcb *)xig;  			if (!check_ksize(xip->xi_len, struct xinpcb)) @@ -1159,7 +1167,7 @@ displaysock(struct sock *s, int pos)  	faddr = s->faddr;  	first = 1;  	while (laddr != NULL || faddr != NULL) { -		offset = 37; +		offset = 40;  		while (pos < offset)  			pos += xprintf(" ");  		switch (s->family) { @@ -1296,7 +1304,7 @@ displaysock(struct sock *s, int pos)  			}  			offset += 7;  		} -		if (opt_s) { +		if (opt_s && show_path_state) {  			if (faddr != NULL &&  			    s->proto == IPPROTO_SCTP &&  			    s->state != SCTP_CLOSED && @@ -1387,7 +1395,7 @@ display(void)  	int n, pos;  	if (opt_q != 1) { -		printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s", +		printf("%-8s %-10s %-5s %-3s %-9s %-*s %-*s",  		    "USER", "COMMAND", "PID", "FD", "PROTO",  		    opt_w ? 45 : 21, "LOCAL ADDRESS",  		    opt_w ? 45 : 21, "FOREIGN ADDRESS"); @@ -1401,7 +1409,8 @@ display(void)  		if (opt_U)  			printf(" %-6s", "ENCAPS");  		if (opt_s) { -			printf(" %-12s", "PATH STATE"); +			if (show_path_state) +				printf(" %-12s", "PATH STATE");  			printf(" %-12s", "CONN STATE");  		}  		if (opt_b) diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile index 9260315fb30b..8b0d3e4a6cf0 100644 --- a/usr.bin/tar/Makefile +++ b/usr.bin/tar/Makefile @@ -17,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 34f87cb65ea2..fe3dd3e8e6ed 100644 --- a/usr.bin/tar/tests/Makefile +++ b/usr.bin/tar/tests/Makefile @@ -28,6 +28,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 7193ab58b5a3..b14122f93ae6 100644 --- a/usr.bin/unzip/Makefile +++ b/usr.bin/unzip/Makefile @@ -13,7 +13,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 85fc4b88cd78..fd5254a55912 100644 --- a/usr.bin/unzip/tests/Makefile +++ b/usr.bin/unzip/tests/Makefile @@ -24,7 +24,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=	\  | 
