git: cd09ca5e71a5 - stable/13 - libarchive: merge from vendor branch

From: Martin Matuska <mm_at_FreeBSD.org>
Date: Sat, 04 May 2024 12:37:33 UTC
The branch stable/13 has been updated by mm:

URL: https://cgit.FreeBSD.org/src/commit/?id=cd09ca5e71a541c47752782d0b710bc95d97cbef

commit cd09ca5e71a541c47752782d0b710bc95d97cbef
Author:     Martin Matuska <mm@FreeBSD.org>
AuthorDate: 2023-07-24 05:42:43 +0000
Commit:     Martin Matuska <mm@FreeBSD.org>
CommitDate: 2024-05-04 11:53:07 +0000

    libarchive: merge from vendor branch
    
    Libarchive 3.7.0
    
    Important changes (relevant to FreeBSD):
      #1814 Do not account for NULL terminator when comparing with "TRAILER!!!"
      #1818 Add ability to produce multi-frame zstd archives
      #1840 year 2038 fix for pax archives on platforms with 64-bit time_t
      #1860 Make single bit bitfields unsigned to avoid clang 16 warning
      #1869 Fix FreeBSD builds with WARNS=6
      #1873 bsdunzip ported to libarchive from FreeBSD
      #1894 read support for zstd compression in 7zip archives
      #1918 ARM64 filter support in 7zip archives
    
    (cherry picked from commit e64fe029e9d3ce476e77a478318e0c3cd201ff08)
---
 contrib/libarchive/NEWS                            |    6 +-
 contrib/libarchive/README.md                       |   16 +-
 contrib/libarchive/SECURITY.md                     |   19 +
 contrib/libarchive/cpio/cpio.c                     |   19 +-
 contrib/libarchive/cpio/test/test_option_J_upper.c |    1 +
 contrib/libarchive/cpio/test/test_option_c.c       |    6 +-
 contrib/libarchive/cpio/test/test_option_t.c       |   17 +-
 contrib/libarchive/libarchive/archive.h            |    4 +-
 contrib/libarchive/libarchive/archive_digest.c     |   60 +
 .../libarchive/libarchive/archive_digest_private.h |   10 +
 contrib/libarchive/libarchive/archive_entry.h      |    2 +-
 contrib/libarchive/libarchive/archive_getdate.c    |  119 +-
 contrib/libarchive/libarchive/archive_hmac.c       |   15 +-
 .../libarchive/libarchive/archive_hmac_private.h   |    2 +
 .../libarchive/archive_openssl_evp_private.h       |    3 +-
 contrib/libarchive/libarchive/archive_random.c     |   35 +-
 .../libarchive/archive_read_data_into_fd.c         |    7 +-
 .../libarchive/archive_read_disk_posix.c           |   28 +
 .../libarchive/libarchive/archive_read_open_file.c |    4 +-
 .../libarchive/archive_read_set_options.3          |   21 +
 .../libarchive/archive_read_support_filter_zstd.c  |   14 +-
 .../libarchive/archive_read_support_format_7zip.c  |  196 +++-
 .../libarchive/archive_read_support_format_cab.c   |    8 +-
 .../libarchive/archive_read_support_format_cpio.c  |    6 +-
 .../archive_read_support_format_iso9660.c          |   12 +-
 .../libarchive/archive_read_support_format_lha.c   |   16 +-
 .../libarchive/archive_read_support_format_mtree.c |    8 +-
 .../libarchive/archive_read_support_format_rar.c   |   17 +-
 .../libarchive/archive_read_support_format_warc.c  |    6 +-
 .../libarchive/archive_read_support_format_xar.c   |    8 +-
 .../libarchive/archive_read_support_format_zip.c   |    2 +-
 contrib/libarchive/libarchive/archive_string.c     |    4 +
 contrib/libarchive/libarchive/archive_util.c       |   57 +-
 contrib/libarchive/libarchive/archive_write.c      |   31 +
 .../libarchive/archive_write_add_filter_compress.c |    2 +-
 .../libarchive/archive_write_add_filter_zstd.c     |  233 ++--
 .../libarchive/archive_write_disk_posix.c          |   65 +-
 .../libarchive/libarchive/archive_write_private.h  |    1 +
 .../libarchive/archive_write_set_format_iso9660.c  |   18 +-
 .../libarchive/archive_write_set_format_pax.c      |   27 +-
 .../libarchive/archive_write_set_format_warc.c     |   25 +-
 .../libarchive/archive_write_set_format_xar.c      |   10 +-
 .../libarchive/archive_write_set_format_zip.c      |   19 +-
 contrib/libarchive/libarchive/test/test_fuzz.c     |    5 +-
 .../test/test_read_disk_directory_traversals.c     |    9 +-
 .../libarchive/test/test_read_format_7zip.c        |  346 ++++++
 .../test/test_read_format_7zip_deflate_arm64.7z.uu |   64 ++
 .../test/test_read_format_7zip_lzma2_arm.7z.uu     |   50 +
 .../test/test_read_format_7zip_lzma2_arm64.7z.uu   |   54 +
 .../test/test_read_format_7zip_solid_zstd.7z.uu    |    9 +
 .../test/test_read_format_7zip_zstd.7z.uu          |   12 +
 .../test/test_read_format_7zip_zstd_arm.7z.uu      |   61 +
 .../test/test_read_format_7zip_zstd_bcj.7z.uu      |   56 +
 .../test/test_read_format_7zip_zstd_nobcj.7z.uu    |   56 +
 .../libarchive/test/test_read_format_rar5.c        |    2 +
 .../libarchive/test/test_read_format_zip.c         |    5 +
 .../libarchive/libarchive/test/test_short_writes.c |    2 +
 .../libarchive/test/test_write_filter_zstd.c       |   27 +
 .../test/test_write_format_zip_compression_store.c |   17 +-
 .../libarchive/test/test_write_format_zip_file.c   |   17 +-
 .../test/test_write_format_zip_file_zip64.c        |   17 +-
 contrib/libarchive/libarchive/xxhash.c             |    4 +
 contrib/libarchive/libarchive_fe/passphrase.c      |    6 +
 contrib/libarchive/tar/bsdtar.1                    |   15 +-
 contrib/libarchive/tar/test/test_option_lzma.c     |    1 +
 contrib/libarchive/tar/util.c                      |   17 +-
 contrib/libarchive/test_utils/test_main.c          |   29 +-
 contrib/libarchive/unzip/CMakeLists.txt            |   37 +
 contrib/libarchive/unzip/bsdunzip.1                |  216 ++++
 contrib/libarchive/unzip/bsdunzip.c                | 1186 ++++++++++++++++++++
 contrib/libarchive/unzip/bsdunzip_platform.h       |   83 ++
 contrib/libarchive/unzip/test/CMakeLists.txt       |   80 ++
 contrib/libarchive/unzip/test/test.h               |   40 +
 contrib/libarchive/unzip/test/test_0.c             |   58 +
 contrib/libarchive/unzip/test/test_C.c             |   41 +
 contrib/libarchive/unzip/test/test_L.c             |   44 +
 contrib/libarchive/unzip/test/test_P_encryption.c  |   41 +
 contrib/libarchive/unzip/test/test_Z1.c            |   40 +
 contrib/libarchive/unzip/test/test_basic.c         |   44 +
 contrib/libarchive/unzip/test/test_basic.zip.uu    |   25 +
 contrib/libarchive/unzip/test/test_d.c             |   44 +
 .../libarchive/unzip/test/test_encrypted.zip.uu    |   13 +
 contrib/libarchive/unzip/test/test_glob.c          |   44 +
 contrib/libarchive/unzip/test/test_j.c             |   44 +
 contrib/libarchive/unzip/test/test_n.c             |   48 +
 contrib/libarchive/unzip/test/test_not_exist.c     |   36 +
 contrib/libarchive/unzip/test/test_o.c             |   47 +
 contrib/libarchive/unzip/test/test_p.c             |   39 +
 contrib/libarchive/unzip/test/test_q.c             |   44 +
 contrib/libarchive/unzip/test/test_singlefile.c    |   41 +
 .../libarchive/unzip/test/test_singlefile.zip.uu   |    8 +
 contrib/libarchive/unzip/test/test_t.c             |   39 +
 contrib/libarchive/unzip/test/test_t_bad.c         |   39 +
 contrib/libarchive/unzip/test/test_t_bad.zip.uu    |   25 +
 contrib/libarchive/unzip/test/test_x.c             |   44 +
 lib/libarchive/tests/Makefile                      |    8 +
 96 files changed, 4122 insertions(+), 436 deletions(-)

diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index d6324487691b..61d1ca47340e 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,4 +1,8 @@
-Wed 07, 2022: libarchive 3.6.2 released
+Jul 18, 2023: libarchive 3.7.0 released
+
+Jul 14, 2023: bsdunzip port from FreeBSD
+
+Dec 07, 2022: libarchive 3.6.2 released
 
 Apr 08, 2022: libarchive 3.6.1 released
 
diff --git a/contrib/libarchive/README.md b/contrib/libarchive/README.md
index 404076237871..727ed49856b6 100644
--- a/contrib/libarchive/README.md
+++ b/contrib/libarchive/README.md
@@ -7,7 +7,7 @@ command-line tools that use the libarchive library.
 
 ## Questions?  Issues?
 
-* http://www.libarchive.org is the home for ongoing
+* https://www.libarchive.org is the home for ongoing
   libarchive development, including documentation,
   and links to the libarchive mailing lists.
 * To report an issue, use the issue tracker at
@@ -23,6 +23,7 @@ This distribution bundle includes the following major components:
 * **tar**: the 'bsdtar' program is a full-featured 'tar' implementation built on libarchive
 * **cpio**: the 'bsdcpio' program is a different interface to essentially the same functionality
 * **cat**: the 'bsdcat' program is a simple replacement tool for zcat, bzcat, xzcat, and such
+* **unzip**: the 'bsdunzip' program is a simple replacement tool for Info-ZIP's unzip
 * **examples**: Some small example programs that you may find useful.
 * **examples/minitar**: a compact sample demonstrating use of libarchive.
 * **contrib**:  Various items sent to me by third parties; please contact the authors with any questions.
@@ -87,7 +88,7 @@ Currently, the library automatically detects and reads the following formats:
   * ZIPX archives (with support for bzip2, ppmd8, lzma and xz compressed entries)
   * GNU and BSD 'ar' archives
   * 'mtree' format
-  * 7-Zip archives
+  * 7-Zip archives (including archives that use zstandard compression)
   * Microsoft CAB format
   * LHA and LZH archives
   * RAR and RAR 5.0 archives (with some limitations due to RAR's proprietary status)
@@ -192,6 +193,17 @@ questions we are asked about libarchive:
   functions.  On those platforms, libarchive will use the non-thread-safe
   functions.  Patches to improve this are of great interest to us.
 
+* The function `archive_write_disk_header()` is _not_ thread safe on
+  POSIX machines and could lead to security issue resulting in world
+  writeable directories.  Thus it must be mutexed by the calling code.
+  This is due to calling `umask(oldumask = umask(0))`, which sets the
+  umask for the whole process to 0 for a short time frame.
+  In case other thread calls the same function in parallel, it might
+  get interrupted by it and cause the executable to use umask=0 for the
+  remaining execution.
+  This will then lead to implicitely created directories to have 777
+  permissions without sticky bit.
+
 * In particular, libarchive's modules to read or write a directory
   tree do use `chdir()` to optimize the directory traversals.  This
   can cause problems for programs that expect to do disk access from
diff --git a/contrib/libarchive/SECURITY.md b/contrib/libarchive/SECURITY.md
new file mode 100644
index 000000000000..6ca188b603fe
--- /dev/null
+++ b/contrib/libarchive/SECURITY.md
@@ -0,0 +1,19 @@
+# Security Policy
+
+If you have discovered a security vulnerability in this project, please report it
+privately. **Do not disclose it as a public issue.** This gives us time to work with you
+to fix the issue before public exposure, reducing the chance that the exploit will be
+used before a patch is released.
+
+You may submit the report in the following ways:
+
+- send an email to security@libarchive.de; and/or
+- send us a [private vulnerability report](https://github.com/libarchive/libarchive/security/advisories/new)
+
+Please provide the following information in your report:
+
+- A description of the vulnerability and its impact
+- 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.
diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c
index 847c92d31449..fbeae4133091 100644
--- a/contrib/libarchive/cpio/cpio.c
+++ b/contrib/libarchive/cpio/cpio.c
@@ -442,6 +442,8 @@ main(int argc, char *argv[])
 	archive_match_free(cpio->matching);
 	free_cache(cpio->gname_cache);
 	free_cache(cpio->uname_cache);
+	archive_read_close(cpio->archive_read_disk);
+	archive_read_free(cpio->archive_read_disk);
 	free(cpio->destdir);
 	passphrase_free(cpio->ppbuff);
 	return (cpio->return_value);
@@ -1151,13 +1153,9 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
 	time_t			 mtime;
 	static time_t		 now;
 	struct tm		*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm		tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t			terr;
-	__time64_t		tmptime;
-#endif
 
 	if (!now)
 		time(&now);
@@ -1205,15 +1203,10 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
 	else
 		fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
 #endif
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&mtime, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = mtime;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&mtime);
 #endif
diff --git a/contrib/libarchive/cpio/test/test_option_J_upper.c b/contrib/libarchive/cpio/test/test_option_J_upper.c
index 1d7d05131b3d..e19d599e1ec7 100644
--- a/contrib/libarchive/cpio/test/test_option_J_upper.c
+++ b/contrib/libarchive/cpio/test/test_option_J_upper.c
@@ -43,6 +43,7 @@ DEFINE_TEST(test_option_J_upper)
 		if (strstr(p, "compression not available") != NULL) {
 			skipping("This version of bsdcpio was compiled "
 			    "without xz support");
+			free(p);
 			return;
 		}
 		failure("-J option is broken");
diff --git a/contrib/libarchive/cpio/test/test_option_c.c b/contrib/libarchive/cpio/test/test_option_c.c
index 013caed56030..dfa62c13b13e 100644
--- a/contrib/libarchive/cpio/test/test_option_c.c
+++ b/contrib/libarchive/cpio/test/test_option_c.c
@@ -37,10 +37,10 @@ is_octal(const char *p, size_t l)
 	return (1);
 }
 
-static int
+static long long int
 from_octal(const char *p, size_t l)
 {
-	int r = 0;
+	long long int r = 0;
 
 	while (l > 0) {
 		r *= 8;
@@ -161,7 +161,7 @@ DEFINE_TEST(test_option_c)
 		assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
 		assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
 		assertEqualMem(e + 36, "000001", 6); /* nlink */
-		failure("file entries should have rdev == 0 (dev was 0%o)",
+		failure("file entries should have rdev == 0 (dev was 0%llo)",
 		    from_octal(e + 6, 6));
 		assertEqualMem(e + 42, "000000", 6); /* rdev */
 		t = from_octal(e + 48, 11); /* mtime */
diff --git a/contrib/libarchive/cpio/test/test_option_t.c b/contrib/libarchive/cpio/test/test_option_t.c
index 0f2dda27cc20..9eef0da571c4 100644
--- a/contrib/libarchive/cpio/test/test_option_t.c
+++ b/contrib/libarchive/cpio/test/test_option_t.c
@@ -37,13 +37,9 @@ DEFINE_TEST(test_option_t)
 	char date[32];
 	char date2[32];
 	struct tm *tmptr;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t terr;
-	__time64_t tmptime;
-#endif
 
 	/* List reference archive, make sure the TOC is correct. */
 	extract_reference_file("test_option_t.cpio");
@@ -95,15 +91,10 @@ DEFINE_TEST(test_option_t)
 #ifdef HAVE_LOCALE_H
 	setlocale(LC_ALL, "");
 #endif
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+        tmptr = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
         tmptr = localtime_r(&mtime, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-        tmptime = mtime;
-        terr = _localtime64_s(&tmbuf, &tmptime);
-        if (terr)
-                tmptr = NULL;
-        else
-                tmptr = &tmbuf;
 #else
         tmptr = localtime(&mtime);
 #endif
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index 5fa56de6c9fd..4182cc55d4a4 100644
--- a/contrib/libarchive/libarchive/archive.h
+++ b/contrib/libarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006002
+#define	ARCHIVE_VERSION_NUMBER 3007000
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -157,7 +157,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.6.2"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.7.0"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
diff --git a/contrib/libarchive/libarchive/archive_digest.c b/contrib/libarchive/libarchive/archive_digest.c
index 3361b19ada82..08a9aeb02320 100644
--- a/contrib/libarchive/libarchive/archive_digest.c
+++ b/contrib/libarchive/libarchive/archive_digest.c
@@ -36,6 +36,11 @@
 #error Cannot use both OpenSSL and libmd.
 #endif
 
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
 /*
  * Message digest functions for Windows platform.
  */
@@ -48,6 +53,26 @@
 /*
  * Initialize a Message digest.
  */
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+static int
+win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
+{
+	NTSTATUS status;
+	ctx->valid = 0;
+
+	status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return (ARCHIVE_FAILED);
+	status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
+	if (!BCRYPT_SUCCESS(status)) {
+		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+		return (ARCHIVE_FAILED);
+	}
+
+	ctx->valid = 1;
+	return (ARCHIVE_OK);
+}
+#else
 static int
 win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 {
@@ -70,6 +95,7 @@ win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 	ctx->valid = 1;
 	return (ARCHIVE_OK);
 }
+#endif
 
 /*
  * Update a Message digest.
@@ -81,23 +107,37 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
 	if (!ctx->valid)
 		return (ARCHIVE_FAILED);
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCryptHashData(ctx->hHash,
+		      (PUCHAR)(uintptr_t)buf,
+		      len, 0);
+#else
 	CryptHashData(ctx->hash,
 		      (unsigned char *)(uintptr_t)buf,
 		      (DWORD)len, 0);
+#endif
 	return (ARCHIVE_OK);
 }
 
 static int
 win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
 {
+#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
 	DWORD siglen = (DWORD)bufsize;
+#endif
 
 	if (!ctx->valid)
 		return (ARCHIVE_FAILED);
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
+	BCryptDestroyHash(ctx->hHash);
+	BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+#else
 	CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
 	CryptDestroyHash(ctx->hash);
 	CryptReleaseContext(ctx->cryptProv, 0);
+#endif
 	ctx->valid = 0;
 	return (ARCHIVE_OK);
 }
@@ -276,7 +316,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
 static int
 __archive_md5init(archive_md5_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
+#endif
 }
 
 static int
@@ -659,7 +703,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
 static int
 __archive_sha1init(archive_sha1_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
+#endif
 }
 
 static int
@@ -919,7 +967,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
 static int
 __archive_sha256init(archive_sha256_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
+#endif
 }
 
 static int
@@ -1155,7 +1207,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
 static int
 __archive_sha384init(archive_sha384_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
+#endif
 }
 
 static int
@@ -1415,7 +1471,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
 static int
 __archive_sha512init(archive_sha512_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
+#endif
 }
 
 static int
diff --git a/contrib/libarchive/libarchive/archive_digest_private.h b/contrib/libarchive/libarchive/archive_digest_private.h
index 9b3bd6621bf3..339b4edca48d 100644
--- a/contrib/libarchive/libarchive/archive_digest_private.h
+++ b/contrib/libarchive/libarchive/archive_digest_private.h
@@ -164,6 +164,15 @@
   defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
   defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
   defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+typedef struct {
+  int   valid;
+  BCRYPT_ALG_HANDLE  hAlg;
+  BCRYPT_HASH_HANDLE hHash;
+} Digest_CTX;
+#else
 #include <windows.h>
 #include <wincrypt.h>
 typedef struct {
@@ -172,6 +181,7 @@ typedef struct {
   HCRYPTHASH  hash;
 } Digest_CTX;
 #endif
+#endif
 
 /* typedefs */
 #if defined(ARCHIVE_CRYPTO_MD5_LIBC)
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index ff64a4712a56..74033564396d 100644
--- a/contrib/libarchive/libarchive/archive_entry.h
+++ b/contrib/libarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006002
+#define	ARCHIVE_VERSION_NUMBER 3007000
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
diff --git a/contrib/libarchive/libarchive/archive_getdate.c b/contrib/libarchive/libarchive/archive_getdate.c
index 39e224cb9010..20ab1b1588fe 100644
--- a/contrib/libarchive/libarchive/archive_getdate.c
+++ b/contrib/libarchive/libarchive/archive_getdate.c
@@ -698,13 +698,9 @@ Convert(time_t Month, time_t Day, time_t Year,
 	time_t		Julian;
 	int		i;
 	struct tm	*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	if (Year < 69)
 		Year += 2000;
@@ -731,15 +727,10 @@ Convert(time_t Month, time_t Day, time_t Year,
 	Julian *= DAY;
 	Julian += Timezone;
 	Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Julian, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Julian;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Julian);
 #endif
@@ -755,36 +746,21 @@ DSTcorrect(time_t Start, time_t Future)
 	time_t		StartDay;
 	time_t		FutureDay;
 	struct tm	*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
-
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Start;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Start);
 #endif
 	StartDay = (ltime->tm_hour + 1) % 24;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Future, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Future;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Future);
 #endif
@@ -799,24 +775,15 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
 {
 	struct tm	*tm;
 	time_t	t, now;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__GMTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	t = Start - zone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_GMTIME_R)
 	tm = gmtime_r(&t, &tmbuf);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	terr = _gmtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &tmbuf;
 #else
 	tm = gmtime(&t);
 #endif
@@ -835,25 +802,16 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
 	struct tm	*tm;
 	time_t	Month;
 	time_t	Year;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	if (RelMonth == 0)
 		return 0;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	tm = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Start;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &tmbuf;
 #else
 	tm = localtime(&Start);
 #endif
@@ -993,10 +951,6 @@ __archive_get_date(time_t now, const char *p)
 	time_t		Start;
 	time_t		tod;
 	long		tzone;
-#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	/* Clear out the parsed token array. */
 	memset(tokens, 0, sizeof(tokens));
@@ -1005,36 +959,26 @@ __archive_get_date(time_t now, const char *p)
 	gds = &_gds;
 
 	/* Look up the current time. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	tm = localtime_s(&local, &now) ? NULL : &local;
+#elif defined(HAVE_LOCALTIME_R)
 	tm = localtime_r(&now, &local);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = now;
-	terr = _localtime64_s(&local, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &local;
 #else
 	memset(&local, 0, sizeof(local));
 	tm = localtime(&now);
 #endif
 	if (tm == NULL)
 		return -1;
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
 	local = *tm;
 #endif
 
 	/* Look up UTC if we can and use that to determine the current
 	 * timezone offset. */
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
 	gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = now;
-	terr = _gmtime64_s(&gmt, &tmptime);
-	if (terr)
-		gmt_ptr = NULL;
-	else
-		gmt_ptr = &gmt;
 #else
 	memset(&gmt, 0, sizeof(gmt));
 	gmt_ptr = gmtime(&now);
@@ -1076,15 +1020,10 @@ __archive_get_date(time_t now, const char *p)
 	 * time components instead of the local timezone. */
 	if (gds->HaveZone && gmt_ptr != NULL) {
 		now -= gds->Timezone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+		gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
 		gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
-		tmptime = now;
-		terr = _gmtime64_s(&gmt, &tmptime);
-		if (terr)
-			gmt_ptr = NULL;
-		else
-			gmt_ptr = &gmt;
 #else
 		gmt_ptr = gmtime(&now);
 #endif
diff --git a/contrib/libarchive/libarchive/archive_hmac.c b/contrib/libarchive/libarchive/archive_hmac.c
index 0914f38e3670..edb3bf5abd42 100644
--- a/contrib/libarchive/libarchive/archive_hmac.c
+++ b/contrib/libarchive/libarchive/archive_hmac.c
@@ -231,15 +231,20 @@ static int
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-	OSSL_PARAM params[2];
+	EVP_MAC *mac;
 
-	EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+	char sha1[] = "SHA1";
+	OSSL_PARAM params[] = {
+		OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
+		OSSL_PARAM_END
+	};
+
+	mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
 	*ctx = EVP_MAC_CTX_new(mac);
+	EVP_MAC_free(mac);
 	if (*ctx == NULL)
 		return -1;
-	EVP_MAC_free(mac);
-	params[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)"SHA1", 0);
-	params[1] = OSSL_PARAM_construct_end();
+
 	EVP_MAC_init(*ctx, key, key_len, params);
 #else
 	*ctx = HMAC_CTX_new();
diff --git a/contrib/libarchive/libarchive/archive_hmac_private.h b/contrib/libarchive/libarchive/archive_hmac_private.h
index 50044a045e37..d0fda7f9667a 100644
--- a/contrib/libarchive/libarchive/archive_hmac_private.h
+++ b/contrib/libarchive/libarchive/archive_hmac_private.h
@@ -77,6 +77,8 @@ typedef	struct hmac_sha1_ctx archive_hmac_sha1_ctx;
 #include <openssl/opensslv.h>
 #include <openssl/hmac.h>
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/params.h>
+
 typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
 
 #else
diff --git a/contrib/libarchive/libarchive/archive_openssl_evp_private.h b/contrib/libarchive/libarchive/archive_openssl_evp_private.h
index ebb06702d0c5..8ac4772808e6 100644
--- a/contrib/libarchive/libarchive/archive_openssl_evp_private.h
+++ b/contrib/libarchive/libarchive/archive_openssl_evp_private.h
@@ -33,7 +33,8 @@
 #include <openssl/evp.h>
 #include <openssl/opensslv.h>
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+    (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
 #include <stdlib.h> /* malloc, free */
 #include <string.h> /* memset */
 static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
diff --git a/contrib/libarchive/libarchive/archive_random.c b/contrib/libarchive/libarchive/archive_random.c
index 9d1aa493f0c8..301765acd830 100644
--- a/contrib/libarchive/libarchive/archive_random.c
+++ b/contrib/libarchive/libarchive/archive_random.c
@@ -51,16 +51,27 @@ __FBSDID("$FreeBSD$");
 #include <pthread.h>
 #endif
 
-static void arc4random_buf(void *, size_t);
+static void la_arc4random_buf(void *, size_t);
 
 #endif /* HAVE_ARC4RANDOM_BUF */
 
 #include "archive.h"
 #include "archive_random_private.h"
 
-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
+#elif defined(HAVE_WINCRYPT_H)
 #include <wincrypt.h>
 #endif
+#endif
 
 #ifndef O_CLOEXEC
 #define O_CLOEXEC	0
@@ -75,6 +86,20 @@ int
 archive_random(void *buf, size_t nbytes)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	NTSTATUS status;
+	BCRYPT_ALG_HANDLE hAlg;
+
+	status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return ARCHIVE_FAILED;
+	status = BCryptGenRandom(hAlg, buf, nbytes, 0);
+	BCryptCloseAlgorithmProvider(hAlg, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return ARCHIVE_FAILED;
+
+	return ARCHIVE_OK;
+# else
 	HCRYPTPROV hProv;
 	BOOL success;
 
@@ -92,6 +117,10 @@ archive_random(void *buf, size_t nbytes)
 	}
 	/* TODO: Does this case really happen? */
 	return ARCHIVE_FAILED;
+# endif
+#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
+	la_arc4random_buf(buf, nbytes);
+	return ARCHIVE_OK;
 #else
 	arc4random_buf(buf, nbytes);
 	return ARCHIVE_OK;
@@ -256,7 +285,7 @@ arc4_getbyte(void)
 }
 
 static void
-arc4random_buf(void *_buf, size_t n)
+la_arc4random_buf(void *_buf, size_t n)
 {
 	uint8_t *buf = (uint8_t *)_buf;
 	_ARC4_LOCK();
diff --git a/contrib/libarchive/libarchive/archive_read_data_into_fd.c b/contrib/libarchive/libarchive/archive_read_data_into_fd.c
index 1f210fce146f..81a36125a4ba 100644
--- a/contrib/libarchive/libarchive/archive_read_data_into_fd.c
+++ b/contrib/libarchive/libarchive/archive_read_data_into_fd.c
@@ -95,8 +95,13 @@ archive_read_data_into_fd(struct archive *a, int fd)
 	    "archive_read_data_into_fd");
 
 	can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
-	if (!can_lseek)
+	if (!can_lseek) {
 		nulls = calloc(1, nulls_size);
+		if (!nulls) {
+			r = ARCHIVE_FATAL;
+			goto cleanup;
+		}
+	}
 
 	while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
 	    ARCHIVE_OK) {
diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c
index 5a94ec5d4399..e9657f6a72e8 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c
@@ -1670,6 +1670,11 @@ setup_current_filesystem(struct archive_read_disk *a)
 	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);
 }
@@ -1860,7 +1865,16 @@ setup_current_filesystem(struct archive_read_disk *a)
 
 #if defined(USE_READDIR_R)
 	/* Set maximum filename length. */
+#if defined(HAVE_STATVFS)
+	t->current_filesystem->name_max = svfs.f_namelen;
+#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);
 }
@@ -1942,6 +1956,11 @@ setup_current_filesystem(struct archive_read_disk *a)
 #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);
 }
@@ -1996,6 +2015,11 @@ setup_current_filesystem(struct archive_read_disk *a)
 	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);
 }
@@ -2543,7 +2567,11 @@ tree_current_lstat(struct tree *t)
 #else
 		if (tree_enter_working_dir(t) != 0)
 			return NULL;
+#ifdef HAVE_LSTAT
 		if (lstat(tree_current_access_path(t), &t->lst) != 0)
+#else
+		if (la_stat(tree_current_access_path(t), &t->lst) != 0)
+#endif
 #endif
 			return NULL;
 		t->flags |= hasLstat;
diff --git a/contrib/libarchive/libarchive/archive_read_open_file.c b/contrib/libarchive/libarchive/archive_read_open_file.c
index 6001dfd47780..c9dcbb1cfec1 100644
--- a/contrib/libarchive/libarchive/archive_read_open_file.c
+++ b/contrib/libarchive/libarchive/archive_read_open_file.c
@@ -154,10 +154,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
*** 5576 LINES SKIPPED ***