untrusted comment: verify with openbsd-70-base.pub
RWR3KL+gSr4QZ8htJ0gGl5XaJF9mmFitS3c5XUZ20Ob4Kk52jdXZ8uWUemFj+YLjbFoXYtGEYVJH46c5wEXoiFSdjXtQQiIutgs=
OpenBSD 7.0 errata 013, February 2, 2022:
Fix two security issues in libexpat related to integer overflow.
Apply by doing:
signify -Vep /etc/signify/openbsd-70-base.pub -x 013_expat.patch.sig \
-m - | (cd /usr/src && patch -p0)
And then rebuild and install libexpat:
cd /usr/src/lib/libexpat
make obj
make
make install
Index: lib/libexpat/Changes
===================================================================
RCS file: /cvs/src/lib/libexpat/Changes,v
retrieving revision 1.17.2.1
diff -u -p -r1.17.2.1 Changes
--- lib/libexpat/Changes 17 Jan 2022 20:58:22 -0000 1.17.2.1
+++ lib/libexpat/Changes 30 Jan 2022 23:12:44 -0000
@@ -2,6 +2,38 @@ NOTE: We are looking for help with a few
https://github.com/libexpat/libexpat/labels/help%20wanted
If you can help, please get in touch. Thanks!
+Release 2.4.4 Sun January 30 2022
+ Security fixes:
+ #550 CVE-2022-23852 -- Fix signed integer overflow
+ (undefined behavior) in function XML_GetBuffer
+ (that is also called by function XML_Parse internally)
+ for when XML_CONTEXT_BYTES is defined to >0 (which is both
+ common and default).
+ Impact is denial of service or more.
+ #551 CVE-2022-23990 -- Fix unsigned integer overflow in function
+ doProlog triggered by large content in element type
+ declarations when there is an element declaration handler
+ present (from a prior call to XML_SetElementDeclHandler).
+ Impact is denial of service or more.
+
+ Bug fixes:
+ #544 #545 xmlwf: Fix a memory leak on output file opening error
+
+ Other changes:
+ #546 Autotools: Fix broken CMake support under Cygwin
+ #554 Windows: Add missing files to the installer to fix
+ compilation with CMake from installed sources
+ #552 #554 Version info bumped from 9:3:8 to 9:4:8;
+ see https://verbump.de/ for what these numbers do
+
+ Special thanks to:
+ Carlo Bramini
+ hwt0415
+ Roland Illig
+ Samanta Navarro
+ and
+ Clang LeakSan and the Clang team
+
Release 2.4.3 Sun January 16 2022
Security fixes:
#531 #534 CVE-2021-45960 -- Fix issues with left shifts by >=29 places
Index: lib/libexpat/README.md
===================================================================
RCS file: /cvs/src/lib/libexpat/README.md,v
retrieving revision 1.9.2.1
diff -u -p -r1.9.2.1 README.md
--- lib/libexpat/README.md 17 Jan 2022 20:58:22 -0000 1.9.2.1
+++ lib/libexpat/README.md 30 Jan 2022 23:12:44 -0000
@@ -5,7 +5,7 @@
[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
-# Expat, Release 2.4.3
+# Expat, Release 2.4.4
This is Expat, a C library for parsing XML, started by
[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
Index: lib/libexpat/doc/reference.html
===================================================================
RCS file: /cvs/src/lib/libexpat/doc/reference.html,v
retrieving revision 1.13.2.1
diff -u -p -r1.13.2.1 reference.html
--- lib/libexpat/doc/reference.html 17 Jan 2022 20:58:22 -0000 1.13.2.1
+++ lib/libexpat/doc/reference.html 30 Jan 2022 23:12:51 -0000
@@ -49,7 +49,7 @@
Index: lib/libexpat/lib/expat.h
===================================================================
RCS file: /cvs/src/lib/libexpat/lib/expat.h,v
retrieving revision 1.17.2.1
diff -u -p -r1.17.2.1 expat.h
--- lib/libexpat/lib/expat.h 17 Jan 2022 20:58:22 -0000 1.17.2.1
+++ lib/libexpat/lib/expat.h 30 Jan 2022 23:12:53 -0000
@@ -1041,7 +1041,7 @@ XML_SetBillionLaughsAttackProtectionActi
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 4
-#define XML_MICRO_VERSION 3
+#define XML_MICRO_VERSION 4
#ifdef __cplusplus
}
Index: lib/libexpat/lib/xmlparse.c
===================================================================
RCS file: /cvs/src/lib/libexpat/lib/xmlparse.c,v
retrieving revision 1.29.2.1
diff -u -p -r1.29.2.1 xmlparse.c
--- lib/libexpat/lib/xmlparse.c 17 Jan 2022 20:58:22 -0000 1.29.2.1
+++ lib/libexpat/lib/xmlparse.c 30 Jan 2022 23:13:09 -0000
@@ -1,4 +1,4 @@
-/* 9ca2a2fedc35bcb13ba9a134ba5e173020bc2ff5f5a311abf742cec7da1ff26a (2.4.3+)
+/* 2e2c8ce5f11a473d65ec313ab20ceee6afefb355f5405afc06e7204e2e41c8c0 (2.4.4+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -33,6 +33,7 @@
Copyright (c) 2019-2020 Ben Wagner
Copyright (c) 2019 Vadim Zeitlin
Copyright (c) 2021 Dong-hee Na
+ Copyright (c) 2022 Samanta Navarro
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -974,7 +975,7 @@ parserCreate(const XML_Char *encodingNam
if (memsuite) {
XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+ parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = memsuite->malloc_fcn;
@@ -2067,6 +2068,11 @@ XML_GetBuffer(XML_Parser parser, int len
keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
+ /* Detect and prevent integer overflow */
+ if (keep > INT_MAX - neededSize) {
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
neededSize += keep;
#endif /* defined XML_CONTEXT_BYTES */
if (neededSize
@@ -4092,7 +4098,7 @@ initializeEncoding(XML_Parser parser) {
const char *s;
#ifdef XML_UNICODE
char encodingBuf[128];
- /* See comments abount `protoclEncodingName` in parserInit() */
+ /* See comments about `protocolEncodingName` in parserInit() */
if (! parser->m_protocolEncodingName)
s = NULL;
else {
@@ -5367,7 +5373,7 @@ doProlog(XML_Parser parser, const ENCODI
if (dtd->in_eldecl) {
ELEMENT_TYPE *el;
const XML_Char *name;
- int nameLen;
+ size_t nameLen;
const char *nxt
= (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
int myindex = nextScaffoldPart(parser);
@@ -5383,7 +5389,13 @@ doProlog(XML_Parser parser, const ENCODI
nameLen = 0;
for (; name[nameLen++];)
;
- dtd->contentStringLen += nameLen;
+
+ /* Detect and prevent integer overflow */
+ if (nameLen > UINT_MAX - dtd->contentStringLen) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ dtd->contentStringLen += (unsigned)nameLen;
if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
}
@@ -6536,7 +6548,7 @@ normalizePublicId(XML_Char *publicId) {
static DTD *
dtdCreate(const XML_Memory_Handling_Suite *ms) {
- DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
+ DTD *p = ms->malloc_fcn(sizeof(DTD));
if (p == NULL)
return p;
poolInit(&(p->pool), ms);
@@ -6709,8 +6721,8 @@ dtdCopy(XML_Parser oldParser, DTD *newDt
if (! newE)
return 0;
if (oldE->nDefaultAtts) {
- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
- oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ newE->defaultAtts
+ = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
if (! newE->defaultAtts) {
return 0;
}
@@ -6872,7 +6884,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
/* table->size is a power of 2 */
table->size = (size_t)1 << INIT_POWER;
tsize = table->size * sizeof(NAMED *);
- table->v = (NAMED **)table->mem->malloc_fcn(tsize);
+ table->v = table->mem->malloc_fcn(tsize);
if (! table->v) {
table->size = 0;
return NULL;
@@ -6912,7 +6924,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
}
size_t tsize = newSize * sizeof(NAMED *);
- NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
+ NAMED **newV = table->mem->malloc_fcn(tsize);
if (! newV)
return NULL;
memset(newV, 0, tsize);
@@ -6941,7 +6953,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
}
}
}
- table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
+ table->v[i] = table->mem->malloc_fcn(createSize);
if (! table->v[i])
return NULL;
memset(table->v[i], 0, createSize);
@@ -7229,7 +7241,7 @@ poolGrow(STRING_POOL *pool) {
if (bytesToAllocate == 0)
return XML_FALSE;
- tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
+ tem = pool->mem->malloc_fcn(bytesToAllocate);
if (! tem)
return XML_FALSE;
tem->size = blockSize;
Index: lib/libexpat/tests/runtests.c
===================================================================
RCS file: /cvs/src/lib/libexpat/tests/runtests.c,v
retrieving revision 1.12.2.1
diff -u -p -r1.12.2.1 runtests.c
--- lib/libexpat/tests/runtests.c 17 Jan 2022 20:58:23 -0000 1.12.2.1
+++ lib/libexpat/tests/runtests.c 30 Jan 2022 23:13:38 -0000
@@ -3847,6 +3847,30 @@ START_TEST(test_get_buffer_2) {
}
END_TEST
+/* Test for signed integer overflow CVE-2022-23852 */
+#if defined(XML_CONTEXT_BYTES)
+START_TEST(test_get_buffer_3_overflow) {
+ XML_Parser parser = XML_ParserCreate(NULL);
+ assert(parser != NULL);
+
+ const char *const text = "\n";
+ const int expectedKeepValue = (int)strlen(text);
+
+ // After this call, variable "keep" in XML_GetBuffer will
+ // have value expectedKeepValue
+ if (XML_Parse(parser, text, (int)strlen(text), XML_FALSE /* isFinal */)
+ == XML_STATUS_ERROR)
+ xml_failure(parser);
+
+ assert(expectedKeepValue > 0);
+ if (XML_GetBuffer(parser, INT_MAX - expectedKeepValue + 1) != NULL)
+ fail("enlarging buffer not failed");
+
+ XML_ParserFree(parser);
+}
+END_TEST
+#endif // defined(XML_CONTEXT_BYTES)
+
/* Test position information macros */
START_TEST(test_byte_info_at_end) {
const char *text = "";
@@ -7352,7 +7376,7 @@ START_TEST(test_misc_version) {
fail("Version mismatch");
#if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T)
- if (xcstrcmp(version_text, XCS("expat_2.4.3"))) /* needs bump on releases */
+ if (xcstrcmp(version_text, XCS("expat_2.4.4"))) /* needs bump on releases */
fail("XML_*_VERSION in expat.h out of sync?\n");
#else
/* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T
@@ -11286,7 +11310,7 @@ START_TEST(test_accounting_precision) {
{"", NULL, NULL, 0,
filled_later},
{"", NULL, NULL,
- sizeof(XML_Char) * 5 /* number of predefined entites */, filled_later},
+ sizeof(XML_Char) * 5 /* number of predefined entities */, filled_later},
{"\n"
" \n"
"",
@@ -11296,7 +11320,7 @@ START_TEST(test_accounting_precision) {
{"text", NULL, NULL, 0, filled_later},
{"text1text2", NULL, NULL, 0, filled_later},
{"&'><"", NULL, NULL,
- sizeof(XML_Char) * 5 /* number of predefined entites */, filled_later},
+ sizeof(XML_Char) * 5 /* number of predefined entities */, filled_later},
{"A)", NULL, NULL, 0, filled_later},
/* Prolog */
@@ -11731,6 +11755,9 @@ make_suite(void) {
tcase_add_test(tc_basic, test_empty_parse);
tcase_add_test(tc_basic, test_get_buffer_1);
tcase_add_test(tc_basic, test_get_buffer_2);
+#if defined(XML_CONTEXT_BYTES)
+ tcase_add_test(tc_basic, test_get_buffer_3_overflow);
+#endif
tcase_add_test(tc_basic, test_byte_info_at_end);
tcase_add_test(tc_basic, test_byte_info_at_error);
tcase_add_test(tc_basic, test_byte_info_at_cdata);