The security of software libraries is essential, especially those embedded in high-profile systems. In this long-read post, we’ll dive deep into CVE-2022-22824, an integer overflow vulnerability in the XML parser Expat (aka libexpat), specifically in its defineAttribute function inside xmlparse.c, before version 2.4.3.

We’ll use plain American English, practical code examples, and reference only the highest quality sources. Exploit details will be covered carefully and responsibly. Let's get right into it.

What is Expat?

Expat is a fast streaming XML parser written in C, used by many projects, from KDE and GNOME to embedded firmware. Because it parses arbitrary user-supplied XML, any bug can have a huge impact.

Summary (from NVD CVE-2022-22824)

> defineAttribute in xmlparse.c in Expat (aka libexpat) before 2.4.3 has an integer overflow.

This means maliciously crafted XML data can cause Expat to try allocating insufficient or incorrect memory for attributes, leading to buffer overflows, memory corruption, and potentially remote code execution.

It’s in the function

static ATTRIBUTE_TYPE *
defineAttribute(ELEMENT_TYPE *type, const ENCODING *enc,
                const XML_Char *attName, unsigned(uriNameLen),
                const XML_Char *prefixEnd,
                const XML_Char *declName, int isCdata,
                int isId, XML_Parser parser)
{
    size_t total = (some calculation);
    ATTRIBUTE_TYPE *att;

    att = (ATTRIBUTE_TYPE *)MALLOC(total * sizeof(ATTRIBUTE_TYPE));
    if (!att) return NULL;
    // More logic...
}

The Dangerous Calculation

The key issue arises when calculating total, which determines how many bytes to allocate. If the XML contains data making total larger than can fit in a 32-bit integer, it wraps around to a small value due to integer overflow.

For example

size_t total = attNameLen + prefixLen + extraStuff;

If attNameLen and prefixLen are both huge, their sum exceeds the max value for a 32-bit size (xFFFFFFFF), and the result rolls over, causing a tiny buffer to be allocated. The function then copies too much data into this small buffer.

Here’s a simplified version illustrating the bug

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>

void vulnerable_attribute_define(size_t name_len) {
    // This calculation can overflow!
    size_t total = name_len + 32 + 8; // Oversimplified
    char *buffer = malloc(total);
    if (!buffer) {
        puts("Allocation failed!");
        return;
    }
    // Unsafe copy: writing name_len bytes into buffer
    memset(buffer, 'A', name_len); // Underlying overflow
    free(buffer);
}

int main() {
    // Simulate overflow: name_len big enough to wrap around
    size_t malicious_len = UINT32_MAX - 30;
    vulnerable_attribute_define(malicious_len);
    return ;
}

If name_len is so big that total exceeds the size of size_t, malloc actually allocates a small block, and the subsequent write overruns it, trashing adjacent memory.

1. Untrusted XML Input

If your program parses user-supplied XML using a vulnerable version of Expat, an attacker can craft XML with huge attribute names to trigger this bug.

2. Controlled Overflow

By calculating the precise values, an attacker can make Expat's allocation tiny, but then Expat will try to write far more data than memory allocated, leading to an exploitable overflow.

Denial of Service: Most likely, your application just crashes.

- Remote Code Execution (RCE): With careful heap layout knowledge and luck, an attacker could overwrite adjacent memory, leading to code execution.

4. Example Malicious XML

<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ATTLIST foo bar
  "AAAAAAAA....(VERY LONG STRING)...AAAAA">
]>
<foo bar="very_long_string"/>

By making the value inside bar attribute huge, you can trigger the overflow.

Fix and References

Expat maintainers released version 2.4.3 addressing this flaw, by validating attribute lengths and checking for overflows during calculations.

Official Patch:

Expat Commit for 2.4.3

Release Notes:

Expat 2.4.3 Changelog

NVD Entry:

CVE-2022-22824 on NVD

Upstream Advisory:

Announcement on oss-security

Final Thoughts

Expat is everywhere. Integer overflows like CVE-2022-22824 are notoriously easy to miss and can be extremely dangerous. Even one mathematical oversight can allow attackers to break into or crash software across millions of devices.

If you run or package Expat, act now. Don't let a simple integer overflow become the weakest link in your security!

Further reading

- Full Bug Analysis on oss-security
- libexpat Project Home
- Detailed Writeup: Talos Report


*Post written exclusively for you, in clear language, with direct code explanations. Please credit and link when sharing.*

Timeline

Published on: 01/10/2022 14:12:00 UTC
Last modified on: 06/14/2022 11:15:00 UTC