Date: Thu, 02 Jul 2026 04:14:59 +0000 From: Philip Paeps <philip@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 32652bf4040c - stable/15 - contrib/expat: import expat 2.8.2 Message-ID: <6a45e5c3.43cca.50d093f@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/15 has been updated by philip: URL: https://cgit.FreeBSD.org/src/commit/?id=32652bf4040ca010924f05e0fce4326b62709c11 commit 32652bf4040ca010924f05e0fce4326b62709c11 Author: Philip Paeps <philip@FreeBSD.org> AuthorDate: 2026-06-25 14:34:28 +0000 Commit: Philip Paeps <philip@FreeBSD.org> CommitDate: 2026-07-02 03:06:35 +0000 contrib/expat: import expat 2.8.2 Changes: https://github.com/libexpat/libexpat/blob/R_2_8_2/expat/Changes Security: CVE-2026-50219 Security: CVE-2026-56131 Security: CVE-2026-56132 Security: CVE-2026-56403 Security: CVE-2026-56404 Security: CVE-2026-56405 Security: CVE-2026-56406 Security: CVE-2026-56407 Security: CVE-2026-56408 Security: CVE-2026-56409 Security: CVE-2026-56410 Security: CVE-2026-56411 Security: CVE-2026-56412 (cherry picked from commit c82aeee8a6d39371006f5eeb1b51704e7b97e2b7) --- contrib/expat/Changes | 92 ++- contrib/expat/README.md | 5 +- contrib/expat/configure.ac | 23 +- contrib/expat/doc/reference.html | 6 +- contrib/expat/doc/xmlwf.1 | 2 +- contrib/expat/doc/xmlwf.xml | 2 +- contrib/expat/lib/Makefile.am | 5 + contrib/expat/lib/Makefile.in | 5 + contrib/expat/lib/expat.h | 2 +- contrib/expat/lib/fallthrough.h | 49 ++ contrib/expat/lib/memory_sanitizer.h | 51 ++ contrib/expat/lib/random_arc4random_buf.c | 4 + contrib/expat/lib/random_dev_urandom.c | 4 +- contrib/expat/lib/random_getentropy.c | 8 +- contrib/expat/lib/random_getrandom.c | 11 +- contrib/expat/lib/siphash.h | 15 +- contrib/expat/lib/xcsinc.c | 48 ++ contrib/expat/lib/xmlparse.c | 1208 ++++++++++++++++------------- contrib/expat/lib/xmltok.c | 6 +- contrib/expat/lib/xmltok_impl.c | 21 +- contrib/expat/tests/acc_tests.c | 6 +- contrib/expat/tests/alloc_tests.c | 6 +- contrib/expat/tests/basic_tests.c | 48 +- contrib/expat/tests/chardata.c | 14 +- contrib/expat/tests/common.c | 5 +- contrib/expat/tests/handlers.c | 53 +- contrib/expat/tests/handlers.h | 14 + contrib/expat/tests/misc_tests.c | 42 +- contrib/expat/xmlwf/filemap.h | 3 +- contrib/expat/xmlwf/win32filemap.c | 2 +- contrib/expat/xmlwf/xmlfile.c | 18 +- contrib/expat/xmlwf/xmlwf.c | 107 ++- contrib/expat/xmlwf/xmlwf_helpgen.py | 2 +- lib/libexpat/expat_config.h | 6 +- lib/libexpat/libbsdxml.3 | 4 +- 35 files changed, 1234 insertions(+), 663 deletions(-) diff --git a/contrib/expat/Changes b/contrib/expat/Changes index 313b3dc60cd0..6a1b89160fb9 100644 --- a/contrib/expat/Changes +++ b/contrib/expat/Changes @@ -29,6 +29,94 @@ !! THANK YOU! Sebastian Pipping -- Berlin, 2026-03-17 !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +Release 2.8.2 Thu June 25 2026 + Security fixes: + #1246 CVE-2026-50219 -- Disallow calls to functions + `XML_GetBuffer`, `XML_Parse`, `XML_ParseBuffer`, + `XML_ParserFree`, `XML_ParserReset` to guard e.g. + Expat bindings from memory corruption; + this CPython issue is related: + https://github.com/python/cpython/issues/146169 + #1267 CVE-2026-56131 -- Protect XML_ResumeParser from being called + from a handler, plugging a hole in the fix + to CVE-2026-50219 + #1272 CVE-2026-56132 -- Fix out-of-bound scaffolding index store + in `doProlog` + #1229 #1232 CVE-2026-56403 -- Integer overflow in `storeAtts` + #1249 CVE-2026-56404 -- Integer overflow in `addBinding` + #1251 CVE-2026-56405 -- Integer overflow in `getAttributeId` + #1255 CVE-2026-56406 -- Integer overflow in `XML_ParseBuffer` + #1262 CVE-2026-56407 -- Integer overflow in `textLen` handling + #565 CVE-2026-56408 -- Integer overflow in `copyString` + (commit 16e2efd867ea8567ffa012210b52ef5918e20817) + #1259 CVE-2026-56409 -- xmlwf: Integer overflow in output path join + #1252 CVE-2026-56410 -- xmlwf: Integer overflow in + `resolveSystemId` + #1263 CVE-2026-56411 -- xmlwf: Integer overflow in notation list + allocation + #1278 CVE-2026-56412 -- Guard XML_TOK_DATA_CHARS handler calls in + `doCdataSection`, plugging a hole in the fix to + CVE-2026-50219 + + Bug fixes: + #1260 xmlwf: Escape names and base URI in meta output + #1266 xmlwf: Pick a safe quote for notation system and public IDs + + Other changes: + #1257 CMake|Autotools: Stop using /dev/urandom by default + #1244 #1254 CMake: Fix guard for Unix sources of entropy + #1183 #1270 CMake|Windows: Add missing export for symbol + `XML_SetHashSalt16Bytes` + #1236 CMake: Mark option EXPAT_OSSFUZZ_BUILD as advanced + #1283 Limit output indentation for EXPAT_ENTITY_DEBUG=1 and + allow unlimited indentation via EXPAT_ENTITY_DEBUG=2 + #565 Replace some loops by use of `memcpy`, `strlen`, `wcslen` + #1220 lib: Use a size_t for group sizes + #1221 lib: Fix too-conservative integer overflow check when + appending raw name + #1222 lib: Simplify attribute allocation/management logic + #1224 Update fallthrough annotations to satisfy Clang and GCC + #1226 lib: Remove unnecessary void * casts in random code + #1228 lib: Reduce scope of locals in storeAtts + #1230 lib: Count attributes with size_t variables + #1238 Minor get-buffer improvements + #1239 #1240 lib|tests: Include header expat_config.h first + #1241 lib: Shrink size of XML_GetBuffer + #1242 lib: Remove a legacy comment + #1243 lib: XML_ParserReset: Extract repeated linked-list move logic + #1243 lib: Unify entity free lists + #1247 lib: Fix use of '0' as boolean literal + #1248 lib: Make XML_Index overflow check more intuitive + #1256 lib: Use size_t for counting string/URI lengths + #1258 lib: XML_GetInputContext: Remove use of 0 for NULL + #1261 Comment typo fixes + #1275 Teach Memory Sanitizer semantics of randomization functions + #1276 #1281 Version info bumped from 13:1:12 (libexpat*.so.1.12.1) + to 13:2:12 (libexpat*.so.1.12.2); see https://verbump.de/ + for what these numbers do + + Infrastructure: + #1231 perl-integration.yml: Bump to XML::Parser 2.59 + #1237 emscripten.yml: Bump from Ubuntu 22.04 to 24.04 + #1183 #1271 windows-build.yml: Cover completeness of file + libexpat.def.cmake + #1274 linux.yml: Make llvm-symbolizer available in CI + + Special thanks to: + Alessandro Gario + Asher Darden + Christoph Reiter + Haris Hussain + Matthew Fernandez + Kartik Kenchi + Nick Begg + Sajin S + Yousef Shanableh + and + Anthropic + Astra Security + Trail of Bits + Release 2.8.1 Sun May 10 2026 Security fixes: #1216 CVE-2026-45186 -- Fix quadratic runtime from attribute name @@ -1820,7 +1908,7 @@ Release 2.1.0 Sat March 24 2012 - Bug Fixes: #1742315: Harmful XML_ParserCreateNS suggestion. #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3. - #1983953, 2517952, 2517962, 2649838: + #1983953, 2517952, 2517962, 2649838: Build modifications using autoreconf instead of buildconf.sh. #2815947, #2884086: OBJEXT and EXEEXT support while building. #2517938: xmlwf should return non-zero exit status if not well-formed. @@ -1846,7 +1934,7 @@ Release 2.1.0 Sat March 24 2012 See bug #2990652 and patch #3312568. Added run-benchmark target to Makefile.in - relies on testdata module present in the same relative location as in the repository. - + Release 2.0.1 Tue June 5 2007 - Fixed bugs #1515266, #1515600: The character data handler's calling of XML_StopParser() was not handled properly; if the parser was diff --git a/contrib/expat/README.md b/contrib/expat/README.md index 7a5ed463b6d5..5ad5e1e85afa 100644 --- a/contrib/expat/README.md +++ b/contrib/expat/README.md @@ -11,7 +11,7 @@ > at the top of the `Changes` file. -# Expat, Release 2.8.1 +# Expat, Release 2.8.2 This is Expat, a C99 library for parsing [XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by @@ -286,9 +286,6 @@ EXPAT_ENABLE_INSTALL:BOOL=ON // Use /MT flag (static CRT) when compiling in MSVC EXPAT_MSVC_STATIC_CRT:BOOL=OFF -// Build fuzzers via OSS-Fuzz for the expat library -EXPAT_OSSFUZZ_BUILD:BOOL=OFF - // Build a shared expat library EXPAT_SHARED_LIBS:BOOL=ON diff --git a/contrib/expat/configure.ac b/contrib/expat/configure.ac index fb492dfd79f7..f14c0308e1c4 100644 --- a/contrib/expat/configure.ac +++ b/contrib/expat/configure.ac @@ -90,7 +90,7 @@ dnl If the API changes incompatibly set LIBAGE back to 0 dnl LIBCURRENT=13 # sync -LIBREVISION=1 # with +LIBREVISION=2 # with LIBAGE=12 # CMakeLists.txt! AC_CONFIG_HEADERS([expat_config.h]) @@ -395,8 +395,23 @@ AC_DEFINE([XML_GE], 1, [Define as 1/0 to enable/disable support for general entities.]) AC_DEFINE([XML_DTD], 1, [Define to make parameter entity parsing functionality available.]) -AC_DEFINE([XML_DEV_URANDOM], 1, - [Define to include code reading entropy from `/dev/urandom'.]) + + +have_dev_urandom=false + +AC_ARG_WITH([dev-urandom], + [AS_HELP_STRING([--with-dev-urandom], + [enforce the use of /dev/urandom in the system @<:@default=no@:>@]) +AS_HELP_STRING([--without-dev-urandom], + [enforce not using /dev/urandom in the system @<:@default=no@:>@])], + [with_dev_urandom=${withval}], + []) + +AS_IF([test "x${with_dev_urandom}" = "xyes"], + [have_dev_urandom=true + AC_DEFINE([XML_DEV_URANDOM], 1, + [Define to include code reading entropy from `/dev/urandom'.])]) + AC_ARG_ENABLE([xml-attr-info], [AS_HELP_STRING([--enable-xml-attr-info], @@ -580,7 +595,7 @@ Entropy sources: getentropy: ${have_getentropy} getrandom: ${have_getrandom_function} syscall SYS_getrandom: ${have_getrandom_syscall} - /dev/urandom: true + /dev/urandom: ${have_dev_urandom} Continue with e.g.: make -j2 diff --git a/contrib/expat/doc/reference.html b/contrib/expat/doc/reference.html index 07d331ed7b56..5c4b1c76ca78 100644 --- a/contrib/expat/doc/reference.html +++ b/contrib/expat/doc/reference.html @@ -53,7 +53,7 @@ <body> <div> <h1> - The Expat XML Parser <small>Release 2.8.1</small> + The Expat XML Parser <small>Release 2.8.2</small> </h1> </div> @@ -1602,7 +1602,9 @@ XML_ParserReset(XML_Parser p, To state the obvious: the three parsing functions <code><a href= "#XML_Parse">XML_Parse</a></code>, <code><a href= "#XML_ParseBuffer">XML_ParseBuffer</a></code> and <code><a href= - "#XML_GetBuffer">XML_GetBuffer</a></code> must not be called from within a + "#XML_GetBuffer">XML_GetBuffer</a></code> as well as the two cleanup functions + <code><a href="#XML_ParserFree">XML_ParserFree</a></code> and <code><a href= + "#XML_ParserReset">XML_ParserReset</a></code> must not be called from within a handler unless they operate on a separate parser instance, that is, one that did not call the handler. For example, it is OK to call the parsing functions from within an <code>XML_ExternalEntityRefHandler</code>, if they apply to the parser diff --git a/contrib/expat/doc/xmlwf.1 b/contrib/expat/doc/xmlwf.1 index 12760944a5da..3de559ec1bb3 100644 --- a/contrib/expat/doc/xmlwf.1 +++ b/contrib/expat/doc/xmlwf.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH XMLWF 1 "May 10, 2026" "" "" +.TH XMLWF 1 "June 25, 2026" "" "" .SH NAME xmlwf \- Determines if an XML document is well-formed .SH SYNOPSIS diff --git a/contrib/expat/doc/xmlwf.xml b/contrib/expat/doc/xmlwf.xml index 529dbba16722..7e57cf1346b9 100644 --- a/contrib/expat/doc/xmlwf.xml +++ b/contrib/expat/doc/xmlwf.xml @@ -21,7 +21,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ <!ENTITY dhfirstname "<firstname>Scott</firstname>"> <!ENTITY dhsurname "<surname>Bronson</surname>"> - <!ENTITY dhdate "<date>May 10, 2026</date>"> + <!ENTITY dhdate "<date>June 25, 2026</date>"> <!-- Please adjust this^^ date whenever cutting a new release. --> <!ENTITY dhsection "<manvolnum>1</manvolnum>"> <!ENTITY dhemail "<email>bronson@rinspin.com</email>"> diff --git a/contrib/expat/lib/Makefile.am b/contrib/expat/lib/Makefile.am index 27bf2ab64769..2b6aec2e6bdc 100644 --- a/contrib/expat/lib/Makefile.am +++ b/contrib/expat/lib/Makefile.am @@ -10,6 +10,8 @@ # Copyright (c) 2017 Tomasz Kłoczko <kloczek@fedoraproject.org> # Copyright (c) 2019 David Loffredo <loffredo@steptools.com> # Copyright (c) 2026 Gordon Messmer <gordon.messmer@gmail.com> +# Copyright (c) 2026 Nick Begg <nick@stunttruck.net> +# Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining @@ -112,14 +114,17 @@ EXTRA_DIST = \ asciitab.h \ expat_external.h \ expat.h \ + fallthrough.h \ iasciitab.h \ internal.h \ latin1tab.h \ libexpat.def.cmake \ + memory_sanitizer.h \ nametab.h \ siphash.h \ utf8tab.h \ winconfig.h \ + xcsinc.c \ xmlrole.h \ xmltok.h \ xmltok_impl.c \ diff --git a/contrib/expat/lib/Makefile.in b/contrib/expat/lib/Makefile.in index 4cd6fcfc6088..73db0e584705 100644 --- a/contrib/expat/lib/Makefile.in +++ b/contrib/expat/lib/Makefile.in @@ -26,6 +26,8 @@ # Copyright (c) 2017 Tomasz Kłoczko <kloczek@fedoraproject.org> # Copyright (c) 2019 David Loffredo <loffredo@steptools.com> # Copyright (c) 2026 Gordon Messmer <gordon.messmer@gmail.com> +# Copyright (c) 2026 Nick Begg <nick@stunttruck.net> +# Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining @@ -508,14 +510,17 @@ EXTRA_DIST = \ asciitab.h \ expat_external.h \ expat.h \ + fallthrough.h \ iasciitab.h \ internal.h \ latin1tab.h \ libexpat.def.cmake \ + memory_sanitizer.h \ nametab.h \ siphash.h \ utf8tab.h \ winconfig.h \ + xcsinc.c \ xmlrole.h \ xmltok.h \ xmltok_impl.c \ diff --git a/contrib/expat/lib/expat.h b/contrib/expat/lib/expat.h index ec3f58544cb0..c493c70441c4 100644 --- a/contrib/expat/lib/expat.h +++ b/contrib/expat/lib/expat.h @@ -1094,7 +1094,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); */ # define XML_MAJOR_VERSION 2 # define XML_MINOR_VERSION 8 -# define XML_MICRO_VERSION 1 +# define XML_MICRO_VERSION 2 # ifdef __cplusplus } diff --git a/contrib/expat/lib/fallthrough.h b/contrib/expat/lib/fallthrough.h new file mode 100644 index 000000000000..707dbdd44bfe --- /dev/null +++ b/contrib/expat/lib/fallthrough.h @@ -0,0 +1,49 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2026 Nick Begg <nick@stunttruck.net> + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef FALLTHROUGH_H +# define FALLTHROUGH_H 1 + +// Explicit fallthrough in switch case to avoid warnings +// with compiler flag -Wimplicit-fallthrough. + +# define EXPAT_FALLTHROUGH \ + do { \ + } while (0) + +# if defined(__has_attribute) +# if __has_attribute(fallthrough) +# undef EXPAT_FALLTHROUGH +# define EXPAT_FALLTHROUGH __attribute__((fallthrough)) +# endif +# endif + +#endif // FALLTHROUGH_H diff --git a/contrib/expat/lib/memory_sanitizer.h b/contrib/expat/lib/memory_sanitizer.h new file mode 100644 index 000000000000..a8a8006ccded --- /dev/null +++ b/contrib/expat/lib/memory_sanitizer.h @@ -0,0 +1,51 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if ! defined(MEMORY_SANITIZER_H) +# define MEMORY_SANITIZER_H 1 + +# if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# include <sanitizer/msan_interface.h> + +// inform Memory Sanitizer that [base, base + extent) is now initialized +# define MSAN_UNPOISON(base, extent) __msan_unpoison((base), (extent)) + +# endif +# endif + +# if ! defined(MSAN_UNPOISON) +# define MSAN_UNPOISON(base, extent) \ + do { \ + } while (0) +# endif + +#endif // ! defined(MEMORY_SANITIZER_H) diff --git a/contrib/expat/lib/random_arc4random_buf.c b/contrib/expat/lib/random_arc4random_buf.c index 1476f07ba1a2..5212b9f192ce 100644 --- a/contrib/expat/lib/random_arc4random_buf.c +++ b/contrib/expat/lib/random_arc4random_buf.c @@ -7,6 +7,7 @@ |_| XML parser Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -35,9 +36,12 @@ # define _DEFAULT_SOURCE 1 /* for glibc */ #endif +#include "memory_sanitizer.h" #include <stdlib.h> // for arc4random_buf void writeRandomBytes_arc4random_buf(void *target, size_t count) { arc4random_buf(target, count); + // MSan does not understand `arc4random_buf`, so explain its effects + MSAN_UNPOISON(target, count); } diff --git a/contrib/expat/lib/random_dev_urandom.c b/contrib/expat/lib/random_dev_urandom.c index e508fe9f3e3c..acae6ba4b047 100644 --- a/contrib/expat/lib/random_dev_urandom.c +++ b/contrib/expat/lib/random_dev_urandom.c @@ -49,11 +49,11 @@ writeRandomBytes_dev_urandom(void *target, size_t count) { const int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); if (fd < 0) { - return 0; + return false; } do { - void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); + void *const currentTarget = (char *)target + bytesWrittenTotal; const size_t bytesToWrite = count - bytesWrittenTotal; errno = 0; diff --git a/contrib/expat/lib/random_getentropy.c b/contrib/expat/lib/random_getentropy.c index b4be70ed73c1..5cea2d8838b9 100644 --- a/contrib/expat/lib/random_getentropy.c +++ b/contrib/expat/lib/random_getentropy.c @@ -7,6 +7,7 @@ |_| XML parser Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -45,10 +46,15 @@ # include <unistd.h> #endif // ! defined(__APPLE__) +#include "memory_sanitizer.h" #include <errno.h> bool writeRandomBytes_getentropy(void *target, size_t count) { errno = 0; - return getentropy(target, count) == 0; + const bool success = getentropy(target, count); + // MSan does not understand `getentropy`, so explain its effects + if (success) + MSAN_UNPOISON(target, count); + return success; } diff --git a/contrib/expat/lib/random_getrandom.c b/contrib/expat/lib/random_getrandom.c index e5724a211cc6..72e2cc7093be 100644 --- a/contrib/expat/lib/random_getrandom.c +++ b/contrib/expat/lib/random_getrandom.c @@ -32,10 +32,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "random_getrandom.h" - #include "expat_config.h" // for HAVE_GETRANDOM, HAVE_SYSCALL_GETRANDOM +#include "random_getrandom.h" + #if defined(HAVE_GETRANDOM) # include <sys/random.h> /* getrandom */ #endif @@ -52,6 +52,7 @@ # define GRND_NONBLOCK 0x0001 #endif /* defined(GRND_NONBLOCK) */ +#include "memory_sanitizer.h" #include <assert.h> #include <errno.h> #include <limits.h> // for INT_MAX @@ -64,7 +65,7 @@ writeRandomBytes_getrandom_nonblock(void *target, size_t count) { const unsigned int getrandomFlags = GRND_NONBLOCK; do { - void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); + void *const currentTarget = (char *)target + bytesWrittenTotal; const size_t bytesToWrite = count - bytesWrittenTotal; assert(bytesToWrite <= INT_MAX); @@ -74,9 +75,13 @@ writeRandomBytes_getrandom_nonblock(void *target, size_t count) { const int bytesWrittenMore = #if defined(HAVE_GETRANDOM) (int)getrandom(currentTarget, bytesToWrite, getrandomFlags); + // MSan understands `getrandom`, so does not need extra guidance #else (int)syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); + // MSan does not understand `syscall`, so explain its effects + if (bytesWrittenMore > 0) + MSAN_UNPOISON(currentTarget, bytesWrittenMore); #endif if (bytesWrittenMore > 0) { diff --git a/contrib/expat/lib/siphash.h b/contrib/expat/lib/siphash.h index 04f6f74585b5..be216b4006dc 100644 --- a/contrib/expat/lib/siphash.h +++ b/contrib/expat/lib/siphash.h @@ -100,6 +100,7 @@ #include <stddef.h> /* size_t */ #include <stdint.h> /* uint64_t uint32_t uint8_t */ +#include "fallthrough.h" /* * Workaround to not require a C++11 compiler for using ULL suffix @@ -234,25 +235,25 @@ sip24_final(struct siphash *H) { switch (left) { case 7: b |= (uint64_t)H->buf[6] << 48; - /* fall through */ + EXPAT_FALLTHROUGH; case 6: b |= (uint64_t)H->buf[5] << 40; - /* fall through */ + EXPAT_FALLTHROUGH; case 5: b |= (uint64_t)H->buf[4] << 32; - /* fall through */ + EXPAT_FALLTHROUGH; case 4: b |= (uint64_t)H->buf[3] << 24; - /* fall through */ + EXPAT_FALLTHROUGH; case 3: b |= (uint64_t)H->buf[2] << 16; - /* fall through */ + EXPAT_FALLTHROUGH; case 2: b |= (uint64_t)H->buf[1] << 8; - /* fall through */ + EXPAT_FALLTHROUGH; case 1: b |= (uint64_t)H->buf[0] << 0; - /* fall through */ + EXPAT_FALLTHROUGH; case 0: break; } diff --git a/contrib/expat/lib/xcsinc.c b/contrib/expat/lib/xcsinc.c new file mode 100644 index 000000000000..3597c2480bc9 --- /dev/null +++ b/contrib/expat/lib/xcsinc.c @@ -0,0 +1,48 @@ +/* This file is included from other .c files! + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2022 Sebastian Pipping <sebastian@pipping.org> + Licensed under the MIT license: + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +static size_t +xcslen(const XML_Char *s) { +#ifdef XML_UNICODE +# ifdef XML_UNICODE_WCHAR_T + return wcslen(s); +# else + // XML_Char is unsigned short + size_t len = 0; + while (s[len]) { + len++; + } + return len; +# endif +#else + return strlen(s); +#endif +} diff --git a/contrib/expat/lib/xmlparse.c b/contrib/expat/lib/xmlparse.c index 890a9389f15d..60f6cc700548 100644 --- a/contrib/expat/lib/xmlparse.c +++ b/contrib/expat/lib/xmlparse.c @@ -1,4 +1,4 @@ -/* 75ef4224f81c052e9e5aeea2ac7de75357d2169ff9908e39edc08b9dc3052513 (2.8.1+) +/* 5de44e6750c6cc78818f06ed552f522a1241df0299395250e1792cb339389daf (2.8.2+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -47,6 +47,9 @@ Copyright (c) 2026 Rosen Penev <rosenp@gmail.com> Copyright (c) 2026 Francesco Bertolaccini Copyright (c) 2026 Christian Ng <christianrng@berkeley.edu> + Copyright (c) 2026 Nick Begg <nick@stunttruck.net> + Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com> + Copyright (c) 2026 Haris Hussain <hextheshadow0x@gmail.com> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -90,7 +93,7 @@ #include <stddef.h> #include <string.h> /* memset(), memcpy() */ #include <assert.h> -#include <limits.h> /* INT_MAX, UINT_MAX */ +#include <limits.h> /* INT_MAX, LLONG_MAX, LONG_MAX, UINT_MAX */ #include <stdio.h> /* fprintf */ #include <stdlib.h> /* getenv */ #include <stdint.h> /* SIZE_MAX, uintptr_t */ @@ -114,6 +117,7 @@ #include "ascii.h" #include "expat.h" #include "siphash.h" +#include "xcsinc.c" #if defined(HAVE_ARC4RANDOM) # include "random_arc4random.h" @@ -156,7 +160,7 @@ * Windows >=Vista (rand_s): _WIN32. \ \ If you insist on not using any of these, bypass this error by defining \ - XML_POOR_ENTROPY; you have been warned. \ + XML_POOR_ENTROPY and be vulnerable to hash flooding; you have been warned. \ \ If you have reasons to patch this detection code away or need changes \ to the build system, please open a bug. Thank you! @@ -207,6 +211,12 @@ typedef char ICHAR; #endif +#ifdef XML_LARGE_SIZE +# define XML_INDEX_MAX LLONG_MAX +#else +# define XML_INDEX_MAX LONG_MAX +#endif + /* Round up n to be a multiple of sz, where sz is a power of 2. */ #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) @@ -270,8 +280,8 @@ typedef struct binding { struct binding *prevPrefixBinding; const struct attribute_id *attId; XML_Char *uri; - int uriLen; - int uriAlloc; + size_t uriLen; + size_t uriAlloc; } BINDING; typedef struct prefix { @@ -283,9 +293,9 @@ typedef struct { const XML_Char *str; const XML_Char *localPart; const XML_Char *prefix; - int strLen; - int uriLen; - int prefixLen; + size_t strLen; + size_t uriLen; + size_t prefixLen; } TAG_NAME; /* TAG represents an open element. @@ -384,8 +394,8 @@ typedef struct { const XML_Char *name; PREFIX *prefix; const ATTRIBUTE_ID *idAtt; - int nDefaultAtts; - int allocDefaultAtts; + size_t nDefaultAtts; + size_t allocDefaultAtts; DEFAULT_ATTRIBUTE *defaultAtts; HASH_TABLE defaultAttsNames; } ELEMENT_TYPE; @@ -417,6 +427,7 @@ typedef struct { unsigned scaffCount; int scaffLevel; int *scaffIndex; + size_t scaffIndexSize; } DTD; enum EntityType { @@ -588,6 +599,7 @@ static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); +static bool FASTCALL poolGrowUntil(STRING_POOL *pool, size_t needed); static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, const XML_Char *s); static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool, @@ -642,16 +654,40 @@ static XML_Parser getRootParserOf(XML_Parser parser, static unsigned long getDebugLevel(const char *variableName, unsigned long defaultDebugLevel); +static bool poolAppendChar(STRING_POOL *pool, XML_Char c); + +static bool poolAppendChars(STRING_POOL *pool, const XML_Char *s, size_t len); + #define poolStart(pool) ((pool)->start) #define poolLength(pool) ((pool)->ptr - (pool)->start) #define poolChop(pool) ((void)--(pool->ptr)) #define poolLastChar(pool) (((pool)->ptr)[-1]) #define poolDiscard(pool) ((pool)->ptr = (pool)->start) #define poolFinish(pool) ((pool)->start = (pool)->ptr) -#define poolAppendChar(pool, c) \ - (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) + +bool +poolAppendChar(STRING_POOL *pool, XML_Char c) { + if (pool->ptr == pool->end && ! poolGrow(pool)) + return false; + + *(pool->ptr)++ = c; + return true; +} + +bool +poolAppendChars(STRING_POOL *pool, const XML_Char *s, size_t len) { + // Detect and prevent integer overflow + if (len > SIZE_MAX / sizeof(XML_Char)) + return false; + + if (! poolGrowUntil(pool, len)) + return false; + + memcpy(pool->ptr, s, len * sizeof(XML_Char)); + pool->ptr += len; + + return true; +} #if ! defined(XML_TESTING) const @@ -730,11 +766,9 @@ struct XML_ParserStruct { const char *m_eventEndPtr; const char *m_positionPtr; OPEN_INTERNAL_ENTITY *m_openInternalEntities; - OPEN_INTERNAL_ENTITY *m_freeInternalEntities; OPEN_INTERNAL_ENTITY *m_openAttributeEntities; - OPEN_INTERNAL_ENTITY *m_freeAttributeEntities; OPEN_INTERNAL_ENTITY *m_openValueEntities; - OPEN_INTERNAL_ENTITY *m_freeValueEntities; + OPEN_INTERNAL_ENTITY *m_freeEntities; XML_Bool m_defaultExpandInternalEntities; int m_tagLevel; ENTITY *m_declEntity; @@ -754,7 +788,7 @@ struct XML_ParserStruct { TAG *m_freeTagList; BINDING *m_inheritedBindings; BINDING *m_freeBindingList; - int m_attsSize; + size_t m_attsSize; int m_nSpecifiedAtts; int m_idAttIndex; ATTRIBUTE *m_atts; @@ -768,7 +802,7 @@ struct XML_ParserStruct { STRING_POOL m_tempPool; STRING_POOL m_temp2Pool; char *m_groupConnector; - unsigned int m_groupSize; + size_t m_groupSize; XML_Char m_namespaceSeparator; XML_Parser m_parentParser; XML_ParsingStatus m_parsingStatus; @@ -785,6 +819,7 @@ struct XML_ParserStruct { ENTITY_STATS m_entity_stats; #endif XML_Bool m_reenter; + unsigned m_handlerCallDepth; }; #if XML_GE == 1 @@ -1128,6 +1163,23 @@ generate_hash_secret_salt(void) { #endif } +static void +beforeHandler(XML_Parser parser) { + assert(parser->m_handlerCallDepth < UINT_MAX); + parser->m_handlerCallDepth++; +} + +static void +afterHandler(XML_Parser parser) { + assert(parser->m_handlerCallDepth > 0); + parser->m_handlerCallDepth--; +} + +static bool +isCalledFromInsideHandler(XML_Parser parser) { + return parser->m_handlerCallDepth > 0; +} + static enum XML_Error callProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { @@ -1364,9 +1416,7 @@ parserCreate(const XML_Char *encodingName, parser->m_freeBindingList = NULL; parser->m_freeTagList = NULL; - parser->m_freeInternalEntities = NULL; - parser->m_freeAttributeEntities = NULL; - parser->m_freeValueEntities = NULL; + parser->m_freeEntities = NULL; parser->m_groupSize = 0; parser->m_groupConnector = NULL; @@ -1482,6 +1532,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) { parser->m_parsingStatus.parsing = XML_INITIALIZED; // Reentry can only be triggered inside m_processor calls parser->m_reenter = XML_FALSE; + parser->m_handlerCallDepth = 0; #ifdef XML_DTD parser->m_isParamEntity = XML_FALSE; parser->m_useForeignDTD = XML_FALSE; @@ -1515,12 +1566,22 @@ moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { } } +/* Moves a list of entities onto the start of another list. */ +static void +moveEntityList(OPEN_INTERNAL_ENTITY **dst, OPEN_INTERNAL_ENTITY **src) { + for (OPEN_INTERNAL_ENTITY *head = *src; head != NULL;) { + OPEN_INTERNAL_ENTITY *const openEntity = head; + head = head->next; + openEntity->next = *dst; + *dst = openEntity; + } +} + XML_Bool XMLCALL XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; - OPEN_INTERNAL_ENTITY *openEntityList; - if (parser == NULL) + if ((parser == NULL) || isCalledFromInsideHandler(parser)) return XML_FALSE; if (parser->m_parentParser) @@ -1535,32 +1596,14 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { tag->bindings = NULL; parser->m_freeTagList = tag; } - /* move m_openInternalEntities to m_freeInternalEntities */ - openEntityList = parser->m_openInternalEntities; - while (openEntityList) { - OPEN_INTERNAL_ENTITY *openEntity = openEntityList; - openEntityList = openEntity->next; - openEntity->next = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity; - } - /* move m_openAttributeEntities to m_freeAttributeEntities (i.e. same task but - * for attributes) */ *** 3286 LINES SKIPPED ***home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a45e5c3.43cca.50d093f>
