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 @@

The Expat XML Parser - Release 2.4.3 + Release 2.4.4

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);