Bug 1096593 (CVE-2014-0209)
Summary: | CVE-2014-0209 libXfont: integer overflow of allocations in font metadata file parsing | ||
---|---|---|---|
Product: | [Other] Security Response | Reporter: | Huzaifa S. Sidhpurwala <huzaifas> |
Component: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> |
Status: | CLOSED ERRATA | QA Contact: | |
Severity: | high | Docs Contact: | |
Priority: | high | ||
Version: | unspecified | CC: | btissoir, carnil, jkurik, jrusnack, kem, security-response-team |
Target Milestone: | --- | Keywords: | Security |
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | libXfont 1.4.8, libXfont 1.4.99.901 (1.5.0rc1) | Doc Type: | Bug Fix |
Doc Text: |
A use-after-free flaw was found in the way libXfont processed certain font files when attempting to add a new directory to the font path. A malicious, local user could exploit this issue to potentially execute arbitrary code with the privileges of the X.Org server.
|
Story Points: | --- |
Clone Of: | Environment: | ||
Last Closed: | 2014-11-25 07:46:41 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | 1097397, 1163601, 1163602, 1163603, 1163604, 1165521 | ||
Bug Blocks: | 1096603 |
Description
Huzaifa S. Sidhpurwala
2014-05-12 06:29:16 UTC
Upstream commits: http://cgit.freedesktop.org/xorg/lib/libXfont/commit/?id=05c8020a49416dd8b7510cbba45ce4f3fc81a7dc http://cgit.freedesktop.org/xorg/lib/libXfont/commit/?id=2f5e57317339c526e6eaee1010b0e2ab8089c42e External Reference: http://lists.x.org/archives/xorg-announce/2014-May/002431.html Created libXfont tracking bugs for this issue: Affects: fedora-all [bug 1097397] Statement: (none) libXfont-1.4.8-1.fc20 has been pushed to the Fedora 20 stable repository. If problems still persist, please make note of it in this bug report. libXfont-1.4.8-1.fc19 has been pushed to the Fedora 19 stable repository. If problems still persist, please make note of it in this bug report. I decided to revisit this flaw after a long time and reading the commit message + patch it seems the issue may not really exists. "lexAlias() reads from a file in a loop. It does this by starting with a 64 byte buffer. If that size limit is hit, it does a realloc of the buffer size << 1, basically doubling the needed length every time the length limit is hit. Eventually, this will shift out to 0 (for a length of ~4gig), and that length will be passed on to realloc(). A length of 0 (with a valid pointer) causes realloc to free the buffer on most POSIX platforms, but the caller will still have a pointer to it, leading to use after free issues." When realloc is passed zero via the size arguement, it actually frees the pointer and returns null. If you carefully look at the code, this output is checked via: http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/fontfile/dirfile.c?id=05c8020a49416dd8b7510cbba45ce4f3fc81a7dc#n385 before actually using the pointer. So when nbuf is null, the function bails out, i dont think an issue really exists here. (In reply to Huzaifa S. Sidhpurwala from comment #6) > When realloc is passed zero via the size arguement, it actually frees the > pointer and returns null. I see both Linux and posix man pages say: If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. Glibc info pages do not seem to mention anything about the special size == 0 behavior. Quick look at the code suggests glibc should guarantee NULL. However, there's other thing you're missing. Both tokenBuf and tokenSize are static. Hence if you trigger the post-realloc if (!nbuf) check, tokenBuf will still contain non-NULL pointer to a chunk of memory that was freed in realloc(0), which should lead to use-after-free on the next lexAlias() call, afaics. (In reply to Tomas Hoger from comment #7) > However, there's other thing you're missing. Both tokenBuf and tokenSize > are static. Hence if you trigger the post-realloc if (!nbuf) check, > tokenBuf will still contain non-NULL pointer to a chunk of memory that was > freed in realloc(0), which should lead to use-after-free on the next > lexAlias() call, afaics. There is no next lexAlias() call. When EALLOC is returned by lexAlias(). The calling function ReadFontAlias() breaks out of the loop at: http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/fontfile/dirfile.c?id=05c8020a49416dd8b7510cbba45ce4f3fc81a7dc#n310 Closes the fontfile and bails out. Is there a guarantee that ReadFontAlias() is not called against before process exist, e.g. for the next font file? (In reply to Tomas Hoger from comment #9) > Is there a guarantee that ReadFontAlias() is not called against before > process exist, e.g. for the next font file? ... not called again before process exit ... Here is the call path: Catalogue* () |_ FontFileInitFPE() |_ FontFileReadDirectory() -> Available to devels as an API to libXfont |_ ReadFontAlias() |_ lexAlias() At each level during the call-path, the return value is checked and there is a provision to bail out, if its value is anything but "Successful". FontFileReadDirectory() is available as an API to libXfont. It has a return value as well and developers using this function, should really check it. I am going to ask the package maintainer to re-confirm. There is no value in sending this to upstream at the time. [foreword, I just step up as libX* maintainer, so I may not be 100% accurate] From what I can read in the code, without the CVE patch, this path is possible: FontFileReadDirectory() is called first |_ ReadFontAlias() | |_ lexAlias() -> EALLOC, tokenBuf freed but not NULL, and tokenSize != 0 | |_ -> AllocError |_ -> AllocError A program can then call again FontFileReadDirectory(): FontFileReadDirectory() |_ ReadFontAlias() |_ lexAlias(): count < tokenSize so we use the freed tokenBuf So if a developer does not check the return value of FontFileReadDirectory(), or tries again (you never know, sometime it works the second attempt...), then the CVE is triggered. Based on the analysis in comment #6 and others, it seems like arbitrary code execution with the permissions of the user running Xorg (root user) would indeed be possible in this case. Because of which this issue was re-evaluated to have important security impact. This issue has been addressed in the following products: Red Hat Enterprise Linux 6 Red Hat Enterprise Linux 7 Via RHSA-2014:1870 https://rhn.redhat.com/errata/RHSA-2014-1870.html IssueDescription: A use-after-free flaw was found in the way libXfont processed certain font files when attempting to add a new directory to the font path. A malicious, local user could exploit this issue to potentially execute arbitrary code with the privileges of the X.Org server. This issue has been addressed in the following products: Red Hat Enterprise Linux 5 Via RHSA-2014:1893 https://rhn.redhat.com/errata/RHSA-2014-1893.html |